I'm trying to marshal an array of structs from C# to VC++.
The C++ function looks like this:
void myFunc(tFileListEntry* fileList);
And tFileListEntry
is defined as:
typedef struct FILE_LIST
{
uint16_t FileGroupCounter;
uint32_t FileID;
uint16_t NumbSamples;
} tFileListEntry;
In C# I declared the function like this:
[DllImport("MyLib", EntryPoint = "myFunc", CallingConvention = CallingConvention.Cdecl)]
public static extern void myFunc( [In, MarshalAs(UnmanagedType.LPArray)] tFileListEntry[] fileList);
And tFileListEntry
is defined as:
[StructLayout(LayoutKind.Sequential)]
public class tFileListEntry
{
public tFileListEntry(UInt16 fileGroupCounter, UInt32 fileId, UInt16 numbSamples)
{
FileGroupCounter = fileGroupCounter;
FileID = fileId;
NumbSamples = numbSamples;
}
public UInt16 FileGroupCounter;
public UInt32 FileID;
public UInt16 NumbSamples;
}
I can set a breakpoint in the C# code as well as in the C++ library. On the managed side the values look right, but on the unmanaged side I get only garbage.
I verified with Marshal.SizeOf()
(in C#) and sizeof()
(in C++) that the size of the struct is 12 bytes on both sides, so I don't think that padding/packing is an issue here.
What am I doing wrong?
I think the problem here is that on the C# side you have declared it as a class, not as a struct.
That means when you create the array on the C# side, each element of the array is a reference (4 or 8 bytes depending on the archtecture) not a struct (12 bytes), with the results you are seeing.
Try changing the C# class to struct.