Reputation: 1576
I have a struct like this in C#:
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 17)]
public string StringValue;
public uint IUintValue;
}
And a corresponding struct in native code
struct MyStruct
{
char StringValue[17];
ulong UintValue;
}
My goal is to pass an array of this structs from c# side to c++(native side) using pinvoke. Here is how I use it in c#
[DllImport(@"MyLibrary.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern int SendArray([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]ref MyStruct[] arr, int recordsCount);
and a calling code is:
var array = new MyStruct[10];
//initialize
SendArray(ref array, array.Length);
On native side I have the following function signature:
extern "C" __declspec(dllexport) int SendArray(MyStruct** Arr, int recordsCount);
And it appears o work only for the first element in array. On c++ side I get this array, but only first element is correctly marshaled. The rest of them appears to be trash.
Where is my mistake?
Upvotes: 4
Views: 6884
Reputation: 612884
Your C++ code does not receive an array of structs. It receives an array of pointers to struct. Change the C++ code to be like so:
int SendArray(MyStruct* Arr, int recordsCount);
or perhaps
int SendArray(MyStruct Arr[], int recordsCount);
And then your p/invoke should be
[DllImport(...)]
public static extern int SendArray([In] MyStruct[] arr, int recordsCount);
I am also suspicious of Pack=8
. Are you quite sure?
Upvotes: 4