问题
There are two unmanaged structs
typedef struct multipolynomial
{
int N;
int max_power;
double* X;
double** Y;
} multipolynomial;
typedef struct output
{
double d;
multipolynomial mp;
} output;
and corresponding managed analogs
[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe class Multipolynomial
{
public int n;
public int max_power;
public double* X;
public double** Y;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public unsafe struct Output
{
public double d;
public Multipolynomial mp;
}
And there is native function
__declspec(dllexport) output __cdecl foo()
{
output out;
out.t = 1;
return out;
}
with managed signature
[DllImport("kernel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern Output foo();
that crashes here
Output output = MathKernel.foo();
with explanation "Method's type signature is not PInvoke compatible."
Please point out whats going wrong?
PS: please note that managed analogue for Multipolynomial struct is class
回答1:
MSDN: P/Invoke cannot have non-blittable types as a return value. That's why you are getting the error you are getting. Also, your managed definitions don't match your unmanaged definitions. The unmanaged output
contains multipolynomial
by value, but your managed equivalent contains it by reference (besides, object references are not blittable). The managed Multipolynomial
must be a struct, and you must specify [MarshalAs(UnmanagedType.Struct)]
on the mp
field — see MarshalAs nested structure. In addition, I am unsure whether unsafe pointers are blittable. Replace them with IntPtr
s while you are testing this out, then put the pointers back in.
来源:https://stackoverflow.com/questions/19200615/nested-struct-unmarshalling