P/Invoke with struct array, failed

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
 
W

Willy Denoyette [MVP]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top