Pergunta

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?

Foi útil?

Solução

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.

Outras dicas

Even with Array's you have to use ref or out. And you should use out.

int Get1251Bytes(string source, out byte[] result, Int32 lengthOfResult)
{
    ...
}

For more information about out and ref lokk at the links.

And here the article about arrays

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top