P/Invoke with struct array, failed

  • Thread starter Thread starter Xia Wei
  • Start date Start date
X

Xia Wei

Hi group,

I'v got something wrong with P/Invoke. If I have two structs defined like
this:
typedef struct{
DWORD F1;
}A, *PA;

typedef struct{
A Data[8];
}B, *PB;

Then I define two structs in C# to interop:

[StructLayout(LayoutKind.Sequential)]
struct A{
public uint F1;
}

[StructLayout(LayoutKind.Sequential)]
struct B{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public A[] Data;
}

It seems very easy but it does not works. The following is my test code.

in VC:

extern "C" DLLTEST_API void StructTest(B b)
{
A* a = b.Data;
for(int i = 0;i < 8;i++)
{
cout << a.F1 << endl;
}
}

in C#:

[DllImport(TestDllPath)]
static extern void StructTest(B b);

[STAThread]
static void Main()
{
StructTest(new B());
}

The exception is:
Can not marshal field Data of type B: This type can not be marshaled as a
structure field.

I don't know why. Any one can help me? Thank you very much.

Regards,
Sunmast
 
Xia Wei said:
Hi group,

I'v got something wrong with P/Invoke. If I have two structs defined like
this:
typedef struct{
DWORD F1;
}A, *PA;

typedef struct{
A Data[8];
}B, *PB;

Then I define two structs in C# to interop:

[StructLayout(LayoutKind.Sequential)]
struct A{
public uint F1;
}

[StructLayout(LayoutKind.Sequential)]
struct B{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public A[] Data;
}

It seems very easy but it does not works. The following is my test code.

in VC:

extern "C" DLLTEST_API void StructTest(B b)
{
A* a = b.Data;
for(int i = 0;i < 8;i++)
{
cout << a.F1 << endl;
}
}

in C#:

[DllImport(TestDllPath)]
static extern void StructTest(B b);

[STAThread]
static void Main()
{
StructTest(new B());
}

The exception is:
Can not marshal field Data of type B: This type can not be marshaled as a
structure field.

I don't know why. Any one can help me? Thank you very much.


hmm... because the v1.x marshaler can't handle structures that contain
array's of struct's.
One way to solve this is to flatten your structure like:

[StructLayout(LayoutKind.Sequential)]
struct A{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=8)]
public uint[] F1;
}

Willy.
 
Back
Top