[英]Passing a struct pointer which contains an array as a parameter in C#
我在C ++中有一個函數,並在DLL中導出。 功能是
LONG LOGIN(LPDEVINFO info);
LPDEVINFO
的結構為:
struct{
BYTE sSerialNumber[20];
} *LPDEVINFO;
為了傳遞LPDEVINFO
參數,我在托管代碼中定義了一個類:
class DEVINFO{
Byte[] sSerialNumber = new Byte[20];
}
然后像這樣P / Invoke:
[DllImport ('MyDll.dll')]
public static extern Int32 LOGIN(DEVINFO info);
然后在C#中調用它:
DEVINFO info = new DEVINFO();
Int id = LOGIN(info)
運行此代碼時,出現以下錯誤:
An unhandled exception of type 'System.AccessViolationException' occurred in WindowsFormsApplication1.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
我認為問題是由數組sSerialNumber
引起的。 但是我不知道如何正確定義它。
提前致謝!
使用fixed
關鍵字聲明一個包含固定大小緩沖區的結構:
public unsafe struct DevInfo
{
public fixed byte sSerialNumber[20];
}
有關更多信息,請參見固定大小緩沖區 。
另外,要通過指針傳遞結構(對應於本機端的LPDEVINFO
),請聲明函數,如下所示:
[DllImport ('MyDll.dll')]
public static extern Int32 LOGIN(ref DevInfo info);
並稱之為:
DevInfo info = new DevInfo();
int id = LOGIN(ref info)
我會在這里使用UmanagedType.ByValArray
:
class DEVINFO {
[MarshalAs(UnmanagedType.ByValArray, SizeConst=20)]
public byte[] sSerialNumber;
}
否則對我來說一切都很好。 特別是,最好使用class
而不是struct
來執行此操作。
該函數期望指向結構而不是實際結構的指針。
使用Marshal.StructureToPtr()函數將您的結構轉換為IntPtr。
C#中的示例:
[DllImport("MyDll.dll")]
public static extern Int32 LOGIN(IntPtr info);
...
DEVINFO info = new DEVINFO();
IntPtr infoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(info));
Marshal.StructureToPtr(info, infoPtr, false);
LOGIN(infoPtr);
如果這是一個OUT參數,則由於被調用者對其進行了修改,因此您需要在調用該函數后從中讀取該參數,然后使用Marshal.PtrToStructure將其讀回到托管結構中,如下所示:
DEVINFO info = (DEVINFO)Marshal.PtrToStructure(infoPtr, typeof(DEVINFO));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.