c# P/Invoke : 将带有 IntPtr 的枚举值传递给函数;访问冲突异常
c# P/Invoke : Pass Enum value with IntPtr to Function; AccessViolationException
我正在为 link C 库实现 C# 包装器,但无法将枚举值作为参数传递给以指针作为输入的非托管函数调用。那就是抛出这个异常。代码如下所示:
库中的函数:
int function(infoField Field, void const *value);
C# 元帅:
[DllImport("CLibrary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int function(infoField Field, IntPtr value);
信息字段结构:
public enum infoField {section, options, orientation};
一个枚举类型 'Options' 有 4 个值可供选择:
public enum Options { var1, var2, var3, var4};
我想将 4 个选项之一作为 EnumField = Options 的值传递,如下所示:
IntPtr value = (Intptr)Options.var1;
function (infoField.options, value);
我想我缺少指向枚举类型的指针的正确转换约定。使用 IntPtr 传递枚举值的正确格式应该是什么?
到目前为止,我尝试了几个选项,但在函数调用时得到 AccessViolationException,这意味着内存分配失败或与库期望的类型不匹配。
PS:其他枚举字段的函数封送处理成功。那也是因为值传递对他们来说是字符串值。但特别是对于 'options' 它必须是 4 个枚举选项之一。
通常,C++
枚举数定义如下:
enum class ENUM_FIELD
{
VAR1,
VAR2,
VAR3,
VAR4
};
默认情况下,枚举 class 类型的大小为 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
我正在为 link C 库实现 C# 包装器,但无法将枚举值作为参数传递给以指针作为输入的非托管函数调用。那就是抛出这个异常。代码如下所示:
库中的函数:
int function(infoField Field, void const *value);
C# 元帅:
[DllImport("CLibrary.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int function(infoField Field, IntPtr value);
信息字段结构:
public enum infoField {section, options, orientation};
一个枚举类型 'Options' 有 4 个值可供选择:
public enum Options { var1, var2, var3, var4};
我想将 4 个选项之一作为 EnumField = Options 的值传递,如下所示:
IntPtr value = (Intptr)Options.var1;
function (infoField.options, value);
我想我缺少指向枚举类型的指针的正确转换约定。使用 IntPtr 传递枚举值的正确格式应该是什么? 到目前为止,我尝试了几个选项,但在函数调用时得到 AccessViolationException,这意味着内存分配失败或与库期望的类型不匹配。
PS:其他枚举字段的函数封送处理成功。那也是因为值传递对他们来说是字符串值。但特别是对于 'options' 它必须是 4 个枚举选项之一。
通常,C++
枚举数定义如下:
enum class ENUM_FIELD
{
VAR1,
VAR2,
VAR3,
VAR4
};
默认情况下,枚举 class 类型的大小为 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