Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshalling an array of strings from managed to native code

I have a managed function with the following declaration (both interface and implementation):

[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
String[] ManagedFunction()
{
    String[] foo = new String[1];
    foo[0] = "bar";
    return foo;
}

There is also a native C++ interface with the same methods as the managed interface, inside of that interface, this method has the following declaration:

void ManagedFunction(SAFEARRAY* foo); 

This function is called by native code in the following way:

void NativeFunction(ManagedBinding binding)
{
    CComSafeArray<BSTR> cComSafeArray;
    cComSafeArray.Create(); 
    LPSAFEARRAY safeArray = cComSafeArray.Detach();
    binding.comObject->ManagedFunction(safeArray); 
}

I'm not sure what I'm doing wrong but after my managed function has been called, safeArray appears to have garbage values, somethings going wrong while marshalling the return value back to native code. Could someone with more experience than me with .Net interop please shed some light on this? Also, It might be relevant to mention that I haven't had problems with returning ValueTypes from my managed function (boolean if you're curious), something about returning a String array is messing things up. Thanks!

like image 718
Tejas Sharma Avatar asked Nov 30 '12 23:11

Tejas Sharma


1 Answers

1) Your function return a SAFEARRAY, so why you allocate it before calling function?
2) ManagedFunction supposed to return a SAFEARRAY, so it should get a SAFEARRAY* to be able to return it! so you should say:

LPSAFEARRAY lpsa;
binding.comObject->ManagedFunction(&lpsa);
CComSafeArray<BSTR> cComSafeArray;
cComSafeArray.Attach(lpsa);
like image 132
BigBoss Avatar answered Oct 04 '22 11:10

BigBoss