c# P/调用 : Pass Enum value with IntPtr to Function; AccessViolationException

标签 c# c++ enums pinvoke marshalling

我正在实现 C# 包装器以链接 C 库,但在将枚举值作为参数传递给以指针作为输入的非托管函数调用时遇到了问题。那就是抛出这个异常。代码如下所示:

库中的函数:

int function(infoField Field, void const *value); 

C# 中的编码(marshal):

[DllImport("CLibrary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int function(infoField Field, IntPtr value);

信息字段结构:

public enum infoField {section, options, orientation};

一个枚举类型“选项”有 4 个值可供选择:

public enum Options { var1, var2, var3, var4};

我想将 4 个选项之一作为 EnumField = Options 的值传递,如下所示:

IntPtr value = (Intptr)Options.var1;
function (infoField.options,  value);

我想我缺少指向枚举类型的指针的正确转换约定。使用 IntPtr 传递枚举值的正确格式应该是什么? 到目前为止,我已经尝试了几个选项,但在函数调用时得到了 AccessViolationException,这意味着内存分配失败或与库期望的类型不匹配。

PS:其他枚举字段的函数编码成功。那也是因为值传递对他们来说是字符串值。但特别是对于“选项”,它必须是 4 个枚举选项之一。

最佳答案

通常,C++ 枚举数定义如下:

enum class ENUM_FIELD
{ 
    VAR1, 
    VAR2,
    VAR3,
    VAR4
};

默认情况下,枚举类类型的大小为 int,这意味着您可以将它们转换为 C#,如下所示:

public enum EnumField
{ 
    VAR1, 
    VAR2,
    VAR3,
    VAR4
}

在这种情况下,两个枚举都将在互操作环境中毫无问题地映射。但是如果 C++ 枚举以不同的方式定义,或者如果非托管方法需要不同的类型,您可能需要更改 C# 声明中的基础类型,以便正确映射值。例如:

public enum EnumField : short
{ 
    VAR1, 
    VAR2,
    VAR3,
    VAR4
}

无论如何,我认为问题不是由枚举引起的,而是由作为 const void* 参数传递的内容引起的。将枚举值转换为 IntPtr 对我来说不合适:

UInt32 field = (UInt32)EnumField.VAR1;
GCHandle handle = GCHandle.Alloc(field, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();

// pass the ptr variable to the unmanaged function
// and don't forget to handle.Free() when you are done

关于c# P/调用 : Pass Enum value with IntPtr to Function; AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47723953/

相关文章:

c# - 基于组件的架构 : Replacing an assembly at runtime

c# - 使用统一解析具有多个构造函数的实例

c++ - 枚举值的类型不是 int?

c++ - 类型定义枚举的问题。和 visual studio 2005 中的错误

c# - 拒绝 HTTP 动词的 MVC3 自定义属性

c# - C#房间管理程序

c++ - 将虚拟机作为应用程序的一部分实现的主要好处是什么?

c++ - 无法理解 C 和 C++ 中静态的行为

c++ - Win32 : Changing Program Icon

c# - 当我将具有枚举属性的类的对象序列化为 JSON 时,如果该值为 null,则生成的 json 很无聊