I have a function in C# that is passing an array of structures into a DLL written in C++. The struct is a group of ints and when I read out the data in the DLL all the values come out fine. However if I try to write to the elements from C++ the values never show up when I try to read then back in C#.
C#
[StructLayout(LayoutKind.Sequential)]
struct Box
{
public int x;
public int y;
public int width;
public int height;
}
[StructLayout(LayoutKind.Sequential)]
struct Spot
{
public int x;
public int y;
}
static void TestCvStructs()
{
int len = 100;
Box[] r = new Box[len];
Spot[] p = new Spot[len];
for (int i = 0; i < len; i++)
{
r[i].x = i*10;
r[i].y = i * 200;
r[i].width = r[i].x * 10;
r[i].height = r[i].y * 100 + r[i].x * 5;
p[i].x = i * 8;
p[i].y = i * 12;
}
PassCvStructs(len, r, p);
for (int i = 0; i < len; i++)
{
Console.WriteLine("Point/x:{0} Boxes/x{1}", p[i].x, r[i].x );
}
}
[DllImport(dll)]
private static extern int PassSomeStructs(int count, Box[] boxes, Spot[] points);
C++
typedef struct Box
{
int x;
int y;
int width;
int height;
} Box;
typedef struct Spot
{
int x;
int y;
} Spot;
CPPDLL_API int PassSomeStructs(int arrayLength, Box *boxes, Spot *points)
{
for(int i = 0; i < arrayLength; ++i)
{
printf("Group:%i\n", i);
printf("Rect - x:%i y:%i width:%i length:%i\n", boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
printf("Point - x:%i y:%i\n", points[i].x, points[i].y);
printf("\n");
points[i].x = 3;
boxes[i].x = 1;
}
return 0;
}
I found the answer posted to another question: How to marshall array of structs in C#?
When marshaling apparently the default is to marshal the parameters as In. Otherwise they need to be explicitly declared as Out or In, Out. After specifying that explicitly my code the example now works.
Thanks to his Skeetness for the answer and to antonmarkov for the exposure to the MarshalAs.