![](/img/trans.png)
[英]How do I handle a complex struct return type from a C DLL file within C#?
[英]How do I convert c struct from dll to C#
我正在將應用程序從c ++轉換為C#,並且對處理導入結構的正確方法有疑問。 我正在嘗試將ac dll中的結構轉換為c#c中的結構如下所示
typedef struct card_info
{
ushort r;
ushort s;
enum_a a;
usinged long ul;
ushort n;
ushort* b;
ushort id;
} CARD_INFO;
當我使用[StructLayout(LayoutKind.Sequentaial)]時,數組的大小在c#中為20個字節。 但是,如果看一下我的工作c ++代碼,它是24個字節。 我將C#更改為如下形式:
[StructLayout(LayoutKind.Explicit)]
public struct CardInfo
{
[FieldOffset(0) public ushort r;
[FieldOffset(2) public ushort s;
[FieldOffset(4) public EnumA a;
[FieldOffset(8) public ushort ul;
[FieldOffset(12) public ushort n;
[FieldOffset(16) public UInt32 b;
[FieldOffset(20) public ushort id;
}
這似乎可以編譯,但是我不相信這是執行此操作的正確方法。 請讓我知道這是否正確或是否有更好的方法。
謝謝
usinged long ul;
這是一個錯字,但這絕對不是ushort,而是uint。
也不要使用FieldOffset,讓編譯器將其弄清楚。 現在Marshal.SizeOf()將返回24,插入適當的填充量。 b
成員應為IntPtr btw。
@ Hans的答案是正確的,但是我只添加一些有關調試編組數據的提示,以便您可以看到結果。 我只是實例化一個結構並像這樣創建一個指向它的指針。
CardInfo cardInfo = new CardInfo();
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(cardInfo));
Marshal.StructureToPtr(cardInfo, pointer, false);
在最后一行插入一個斷點,並進入調試器,直到斷點為止。 您應該在locals / autos窗口中看到pointer
,它的值應該是一些int值。 (十六進制顯示在這里效果最好)。
移至“命令”窗口,然后鍵入dc 0x0086bf30
<-指針的地址。 它應該轉儲內存中的數據。 再次輸入dc
將轉儲接下來的內存塊。 您還可以使用da
, db
, dd
, df
, dq
將數據轉儲為不同類型。 接下來嘗試越過斷點(F10),然后再次轉儲相同的內存。
您可以使用特定的值初始化結構的字段,並在此處觀察更改以查看其是否正常工作。
ul
在C實現中是無符號的long,但是您使用的是無符號的short。 如果您想知道為什么StructLayout.Sequential
實現太小,那將是一個不錯的起點。
我還要仔細檢查您的EnumA
實現,以確保其大小正確。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.