Отображение данных байтового массива в структуры в C # - PullRequest
1 голос
/ 21 июля 2011

Я боролся с проблемой слишком много часов, поэтому я перехожу сюда, чтобы узнать, есть ли у кого-нибудь идеи, как решить эту проблему.У меня есть устаревшая программа C ++, которая отправляет пакеты через сокеты.Они содержат структуры C ++, я подумал, что было бы просто определить структуру, похожую на C ++ в моем приложении C #, и просто прочитать байтовый массив.Я заметил, что это не так просто, и я думаю, что я свел проблему к выравниванию, но я действительно не могу обойти это.

Моя структура C ++ выглядит так:

typedef struct
{
    int                  int_1;
    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;

Который, как я думал, я мог бы перевести в структуру C # следующим образом:

[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
        }

Кажется, проблема в том, как C # отображает короткое замыкание (добавляя заполнение в 2 байта?), Что вызывает остальноеструктуры, которая будет плохо выровнена и создает мусорные данные.Можно ли как-то заставить эту работу работать?Я не сомневаюсь в использовании структур в C #, если классы облегчают это.

В результате этого при использовании некоторых тестовых данных кажется, что int_1, long_1 и short_1 получают правильные значения, а все остальное - мусор, этопочему я подозреваю, что проблема в том, что короткое дело здесь.

Любые мысли более чем приветствуются.

/ J

РЕДАКТИРОВАТЬ: Почему у меня 12 вместо 10 дляСмещение строки вызвано тем, что кажется, что символы должны начинаться с четного DWORD, если я вместо этого поставлю 10, как я думаю, должно быть (я действительно знаю, моя математика спасибо)сборка 'SocketAndStructTest, версия = 1.0.0.0, Culture = нейтральная, PublicKeyToken = null', поскольку она содержит поле объекта со смещением 10, которое неправильно выровнено или перекрыто полем необъекта. "

1 Ответ

2 голосов
/ 21 июля 2011

Ваш FieldOffsets не выстроился так, как вы ожидаете.Например, после двух I_4 и I_2 у вас есть FieldOffset(12), тогда как я думаю, что вы захотите FieldOffset(10).

Также я думаю, что вам нужно применить [StructLayout(LayoutKind.Explicit)] к struct.

...