为什么这种封送处理在Mono中工作,但在MS中失败?
本文关键字:工作 但在 MS 失败 Mono 处理 为什么 | 更新日期: 2023-09-27 18:02:16
我已经将其归结为一个简单的例子。我正在编写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();
但是,这会抛出一个异常:
类型为"System.Runtime.InteropServices"的未处理异常。MarshalDirectiveException'发生在ForestDB.Test.exe
附加信息:方法的类型签名不兼容PInvoke。
注意:我已经尝试了各种MarshalAs
组合没有运气。还请注意,我只负责c#方面的事情,C API是由其他人开发的,我无法控制它。
如果这个简单签名不兼容p/Invoke,那到底是什么?为什么它能在Mono的OS X上工作?
你知道什么?事实证明,MarshalAs
实际上是问题所在,使该属性在Windows上几乎毫无用处。托管端的结构体的所有成员都需要是可篡改类型。这个限制在Mono上显然不存在