簡體   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