我将其简化为一个简单的示例。我正在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上运行?
好吧,你知道什么。原来MarshalAs
竟是问题,使得属性在Windows上几乎无用。受管端的结构的所有成员都必须是可Blittable类型的。这种限制显然在Mono上不存在。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句