繁体   English   中英

c#P / Invoke:使用IntPtr将Enum值传递给Function; AccessViolationException

[英]c# P/Invoke : Pass Enum value with IntPtr to Function; AccessViolationException

我正在实现C#包装器来链接C库并且无法将Enum值作为参数传递给Unmanaged函数调用,它将指针作为输入。 这就是抛出这个例外。 代码如下所示:

图书馆的功能:

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);

infoField结构:

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);

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

PS:其他EnumFields的功能封送成功。 这也是因为值传递是它们的字符串值。 但特别是对于'选项',它必须是4个Enum选项之一。

通常, 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对我来说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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM