嵌套的struct unmarshalling

时间:2013-10-05 17:28:32

标签: c# c struct return unmarshalling

有两种非托管结构

typedef struct multipolynomial
{
    int N;
    int max_power;
    double* X;
    double** Y;
} multipolynomial;

typedef struct output
{
    double d;
    multipolynomial mp;
} output;

和相应的管理类似物

[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;
}

还有原生功能

__declspec(dllexport) output __cdecl foo()
{
    output out;
    out.t = 1;
    return out;
}

使用托管签名

[DllImport("kernel.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern Output foo();

崩溃了

Output output = MathKernel.foo();

解释“Method的类型签名不兼容PInvoke。”

请指出哪里出错了?

PS:请注意Multipolynomial struct的托管模拟是 class

1 个答案:

答案 0 :(得分:0)

MSDN:P / Invoke不能将非blittable类型作为返回值。这就是你得到错误的原因。此外,您的托管定义与您的非托管定义不匹配。非托管output按值包含multipolynomial,但您的托管等效项通过引用包含它(此外,对象引用不是blittable)。托管Multipolynomial必须是结构,您必须在[MarshalAs(UnmanagedType.Struct)]字段上指定mp - 请参阅MarshalAs nested structure。另外,我不确定不安全的指针是否是blittable。在测试时将它们替换为IntPtr,然后将指针放回去。