How do I convert c struct from dll to C#
I am converting a application from c++ to C# and have a question about the proper way to handle importing structs. I am attempting to convert a struct from a c dll into c# The struct in c looks like this
typedef struct card_info
{
ushort r;
ushort s;
enum_a a;
usinged long ul;
u开发者_如何学Goshort n;
ushort* b;
ushort id;
} CARD_INFO;
when i use [StructLayout(LayoutKind.Sequentaial)] the size of the array is 20 bytes in c#. However, if take a look at my working c++ code it is 24 bytes. I changed my c# to look like this:
[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;
}
This seems to compile but I'm not convinced this is the correct way to go about doing this. Please let me know if this is correct or if there is a better way.
Thanks
usinged long ul;
It's a typo, but that definitely isn't a ushort, it's an uint.
Don't use FieldOffset either, let the compiler figure it out. Now Marshal.SizeOf() will return 24, the proper amount of padding is inserted. The b
member should be IntPtr btw.
@Hans's answer is correct, but I'll just add some tips on debugging marshalled data so you can see the results. I just instantiate a structure and create a pointer to it like this.
CardInfo cardInfo = new CardInfo();
IntPtr pointer = Marshal.AllocHGlobal(Marshal.SizeOf(cardInfo));
Marshal.StructureToPtr(cardInfo, pointer, false);
Stick a breakpoint on the last line of this and step into the debugger until it breaks. You should see the pointer
in the locals/autos windows, and it's value should be some int value. (Hex display works best here).
Move over to the Command window, and type dc 0x0086bf30
<- the address of your pointer. It should dump out the data in that are of memory. Typing dc
again will dump the next chunks of memory. You can also use da
, db
, dd
, df
, dq
to dump the data as different types. Try stepping over the breakpoint next (F10), and dump the same memory again.
You can initialize the fields of your struct with particular values and observe the changes here to see if it's working as it should.
ul
is an unsigned long in the C implementation but you're using an unsigned short. That would be a good place to start, if you're wondering why your StructLayout.Sequential
implementation is too small.
I'd also double check your EnumA
implementation to make sure it's the right size.
精彩评论