Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# function doesn't update SAFEARRAY

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?

like image 644
Zharro Avatar asked Nov 03 '22 08:11

Zharro


1 Answers

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.

like image 112
Martin Liversage Avatar answered Nov 12 '22 09:11

Martin Liversage