I have a C# function with following signature:
int Get1251Bytes(string source, byte[] result, Int32 lengthOfResult)
I call it from C++. I was informed by compiler that 2-nd param must have SAFEARRAY*
type. So I call it in this way:
SAFEARRAY* safeArray = SafeArrayCreateVector(VT_UI1, 0, arrayLength);
char str[] = {'s', 't', 'a', 'c', 'k', '\0'};
converter->Get1251Bytes(str, safeArray, arrayLength);
But safeArray is not updated, it still contains zores. But I tested Get1251Bytes
function in C# unit-test. It works properly and updates result
array. What am I doing wrong?
Your problem is related to Blittable and Non-Blittable Types (Byte
is blittable):
As an optimization, arrays of blittable types and classes that contain only blittable members are pinned instead of copied during marshaling. These types can appear to be marshaled as In/Out parameters when the caller and callee are in the same apartment. However, these types are actually marshaled as In parameters, and you must apply the InAttribute and OutAttribute attributes if you want to marshal the argument as an In/Out parameter.
To fix your code you need to apply an [Out]
attribute to the result
parameter in the C# code:
int Get1251Bytes(string source, [Out] byte[] result, Int32 lengthOfResult)
Also, you don't need to pass lengthOfResult
. In .NET you can use the Length
property to get the size of the array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With