c# - 为什么此编码在 Mono 中有效但在 MS 中失败?

标签 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();

但是,这会引发异常:

An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in ForestDB.Test.exe

Additional information: Method's type signature is not PInvoke compatible.

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

如果这个简单的签名与 P/Invoke 不兼容,那到底是什么?顺便说一句,为什么它可以在 OS X 的 Mono 上运行?

最佳答案

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

关于c# - 为什么此编码在 Mono 中有效但在 MS 中失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31354476/

相关文章:

c# 如何在 DataGridView 的特定列中强制使用大写?

c# - 从 .Net 4.x 应用程序反射(reflect) WinRT 可执行文件

c# - 如何将 C 函数签名转换为 C# 并在 native DLL 中调用该函数?

c# - C++ <--> C# 修改字节编码数组

c# - 如何将 ProcessInfo 转换为 WTS_PROCESS_INFO

C# 按对象搜索组合框的索引

c# - DPI 意识 - 在一个版本中没有意识到,在另一个版本中有系统意识

c# - 从 C# 动态调用非托管代码

java - 编码失败,但有关此上下文未知的 MarshallerImpl 异常

c# - 将套接字从 .NET 传递到非托管 C++ 代码