我把它简化为一个简单的例子。我在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?
答案 0 :(得分:2)
嗯,你知道什么。结果MarshalAs
实际上是问题,使得该属性在Windows上几乎无用。托管端的结构的所有成员都需要blittable types。 Mono上显然不存在这种限制。