Marshalling an array of structs to a pointer in C#
I am trying to call an unmanaged function that looks like this (DATA is my C# struct):
[DllImport("data.dll")]
internal static unsafe extern int MyExternalFunction(DATA* pData, uint numElements);
This is how I'm calling the function from C#:
DATA[] data = new DATA[64];
fixed (DATA* pData = data )
{
MyExternalFunction(pData, 64);
}
[StructLayout(LayoutKind.Sequential)]
internal struct DATA
{
internal uint a;
internal uint b;
internal uint c;
internal POINT pos;
}
[StructLayout(Layout开发者_如何学GoKind.Sequential)]
internal struct POINT
{
internal int x;
internal int y;
}
Unfortunately I get this error: "Cannot marshal 'parameter #1': Pointers cannot reference marshaled structures."
If it makes any difference, my DATA struct has nested structs inside it. I have no control over how this external method is designed. What is the correct way to call this function and receive an array of structs?
You should declare it like this:
[DllImport("data.dll")]
public static extern int MyExternalFunction(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
DATA[] Data,
uint numElements
);
And call it like this:
MyExternalFunction(myArray, myArray.Length);
No need for unsafe or fixed. Do remove all of that.
try this:
[DllImport("data.dll")]
internal static unsafe extern int MyExternalFunction(DATA[] pData);
and omit the C# pointer altogether.
Edit: I did not test that but it makes sense that the pointer way will not work as the memory layout of managed arrays is not the same as unmanaged ones. The marshaller has to get the chance of taking your array and transform it in native format then back again. I'm not sure if a ref modifier should be required in this case but it might be an option.
精彩评论