开发者

Mapping byte array data to structs in C#

I've been wrestling with a problem for too many hours so I turn here to see if anyone has any idea how to solve this problem. I have a legacy C++ program that sends packets via sockets. These contain C++ structs, I thought that it would be easy to just define a struct looking like the one in C++ in my C# application and just read the byte array. I've noticed it's not that simple and I think I've boiled down the problem to alignment, still I really can't get my head round it.

My C++ struct looks like this:

typedef struct
{
    int                  int_1;
开发者_C百科    short              short_1;
    long               long_1;
    char                char_11[11];
    long               long_2;
    short              short_2;
    int                  int_2;

} TEST_KLIENT_REC, *PTEST_KLIENT_REC;

Which I thought I could translate into a C# struct like this:

[StructLayout(LayoutKind.Explicit, Pack=0)]    
public struct TEST_KLIENT_REC
        {
            [FieldOffset(0)]
            [MarshalAs(UnmanagedType.I4)]
            public int          int_1;          // 4
            [FieldOffset(4)]
            [MarshalAs(UnmanagedType.I2)]
            public short        short_1;        // 2
            [FieldOffset(6)]
            [MarshalAs(UnmanagedType.I4)]
            public int          long_1;         // 4
            [FieldOffset(12)]
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=11)]
            public string       char_11;        // 11
            [FieldOffset(22)]
            [MarshalAs(UnmanagedType.I4)]
            public int          long_2;         // 4
            [FieldOffset(26)]
            [MarshalAs(UnmanagedType.I2)]
            public short        short_2;        // 2
            [FieldOffset(28)]
            [MarshalAs(UnmanagedType.I4)]
            public int          int_2;          // 4
        }

The problem seems to be how C# maps to short (putting in padding of 2 bytes?) which causes the rest of the struct to be badly aligned and creating garbage data. Is it possible to make this work in some way? I'm not fuzzed about using structs in C# if classes makes it easier.

The result of this when using some test data seems to be that int_1, long_1 and short_1 get correct values and everything else is garbage, that's why I suspect the short is the problem here.

Any thoughts are more than welcomed.

/J

EDIT: As to why I have 12 instead of 10 for the string Offset is because it seems char ararys have to start at an even DWORD, if I put 10 instead as I think it should be (I do know my math thank you) I get a crash with "Could not load type 'TEST_KLIENT_REC' from assembly 'SocketAndStructTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 10 that is incorrectly aligned or overlapped by a non-object field."


Your FieldOffsets don't line up the way you'd expect. For example, after two I_4's and an I_2, you have FieldOffset(12), whereas I think you'd want FieldOffset(10).

Also, I think you need to apply [StructLayout(LayoutKind.Explicit)] to the struct.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜