Reputation: 604
I would like to instantiate memory for a boolean array in C# and pass this to a C library function using interop. Then the C function should fill up the array with data (result) so that the data can passed back to C# and used there. Since arrays are reference types and since I explicitly set the [In, Out] marshalling attribute for the array I thought this would be a piece of cake. But apparantly not. :-( Below is some test code (as simple as I could get it) that illuminates the problem.
In C, here is what I will call:
extern "C" __declspec(dllexport) int __stdcall TestFillArray(bool *resultMaterials, int materialLength);
__declspec(dllexport) int __stdcall TestFillArray(bool *resultMaterials, int materialLength)
{
resultMaterials[0] = true;
resultMaterials[1] = true;
return materialLength;
}
I call this function from C# using the following declaration:
[DllImport("FrontAuction2.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern int TestFillArray([MarshalAs(UnmanagedType.LPArray, SizeConst = 2), In, Out] bool[] resultMaterial, int materialLength);
then within my C# test method I have:
var resultMaterials = new bool[2];
var res = TestFillArray(resultMaterials, 2);
When I check the result, I get res=2 and resultMaterials[0] = true, and resultMaterials[1] = false. I.e. the res value is correct as well as the first array element´, but not the second one. So it seems that the boolean data is not marshalled correctly (unless I am missing something obvious).
I am guessing it also would be possible to declare a IntPtr instead of an array and succesfully marshal the two elements to the correct result. However, since I want the array to be allocated in memory in C#, I am not sure how to do this.
Much obliged for help on this. I'm kind of stuck here. :(
UPDATE: I am guessing that it is due to that boolean is only 1 byte long and that the C# code does not get this information. So how do you specify this?
Upvotes: 2
Views: 204
Reputation: 244908
Using
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeConst = 2), In, Out]
should tell the framework to mashal the array as an array of 1-byte bool
s. Another option would be to use the 4-byte BOOL
instead. For more information see UnmanagedType
enum.
Upvotes: 1