为什么这个Marshaling在Mono工作但在MS上失败?

时间:2015-07-11 07:09:32

标签: c# pinvoke marshalling

我把它简化为一个简单的例子。我在C#和C之间编写了一些互操作代码,我在非托管端有非常简单的结构:

typedef struct {
    bool create_if_missing;
    fdb_custom_cmp_variable custom_cmp;
} fdb_kvs_config;

typedef int (*fdb_custom_cmp_variable)(void *a, size_t len_a,
                                   void *b, size_t len_b);

所以我在管理方创建了这个:

public struct fdb_kvs_config
{
    [MarshalAs(UnmanagedType.I1)]
    public bool create_if_missing;

    [MarshalAs(UnmanagedType.FunctionPtr)]
    public IntPtr custom_cmp;
}

我想使用这个非托管函数

extern __declspec(dllexport)
fdb_kvs_config fdb_get_default_kvs_config(void);

所以我有这个等价物:

[DllImport("forestdb", CallingConvention=CallingConvention.Cdecl)]
public static extern fdb_kvs_config fdb_get_default_kvs_config();

然而,这引发了一个例外:

  

ForestDB.Test.exe中出现未处理的“System.Runtime.InteropServices.MarshalDirectiveException”类型异常

     

附加信息:方法的类型签名与PInvoke不兼容。

注意:我尝试了各种MarshalAs组合,没有运气。另请注意,我只负责C#方面的事情,C API是由其他人开发的,我无法控制它。

如果这个简单的签名不是P / Invoke兼容的,那么到底是什么?对于奖励积分,为什么它适用于Mono的OS X?

1 个答案:

答案 0 :(得分:2)

嗯,你知道什么。结果MarshalAs实际上是问题,使得该属性在Windows上几乎无用。托管端的结构的所有成员都需要blittable types。 Mono上显然不存在这种限制。