我正在将应用程序从c ++转换为C#,并对处理导入结构的正确方法有疑问。我试图将结构从c 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;
}
这似乎可以编译,但我不相信这是正确的方法。如果这是正确的或者有更好的方法,请告诉我。
由于
答案 0 :(得分:4)
usinged long ul;
这是一个错字,但这肯定不是一个短暂的,它是一个uint。
不要使用FieldOffset,让编译器搞清楚。现在Marshal.SizeOf()将返回24,插入适当数量的填充。 b
成员应该是IntPtr btw。
答案 1 :(得分:1)
@ 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),然后再次转储相同的内存。
您可以使用特定值初始化结构的字段,并在此处观察更改,看它是否正常工作。
答案 2 :(得分:0)
ul
是C实现中的unsigned long,但是你使用的是unsigned short。如果您想知道为什么StructLayout.Sequential
实施太小,那么这将是一个很好的起点。
我还会仔细检查您的EnumA
实施,以确保其尺寸合适。