Я разработчик C#, пишу клиент для сервера, написанного на C++. Сервер передает какие-то произвольные данные по TCP/IP клиенту, и мы должны собрать их на другом конце. Сервер отправляет нам сначала описание данных, затем сами данные.
Проблемная структура:
struct Inner_S
{
double a;
double b[4][4];
};
#pragma pack(1)
struct Packed_S
{
uint8_t c;
Inner_S d;
};
Сервер сообщает клиенту, что внешняя структура имеет выравнивание 1, а внутренняя структура имеет выравнивание 8. Спецификация протокола говорит:
Выравнивание полей в потоковой структуре выполняется в соответствии со спецификацией 64-разрядного двоичного интерфейса приложений C++ Itanium (т. е. так же, как типичный компилятор GNU на типичной 64-разрядной платформе).
Я нашел спецификацию двоичного интерфейса 64-разрядного приложения Itanium C++. Я думаю, что часть, которую я ищу, находится в разделе «Распределение членов, отличных от виртуальных баз», но я там теряюсь.
На стороне С# я читаю поток данных и упаковываю свой собственный класс со значениями, извлеченными из структуры. Мне нужно знать, где именно в потоке искать каждый элемент структуры.
В настоящее время я обрабатываю структуру таким образом, что, по мнению моих пользователей, это неправильно:
(начать структуру с выравнивания 1)(заполнение не требуется)(читать простое значение)c(начинать внутреннюю структуру с выравнивания 8)(добавить дополнение к выравниванию 8)0000000(прочитать поле)aaaaaaaa(начало массива)(прочитать простое значение)bbbbbbbb. ....
Этот метод поддерживается не менее одного сайта.
Итак, когда я анализирую эти данные, как мне обрабатывать выравнивание в Inner_S
?
caaaaaaaabbbbbbbbb.... (я думаю?) caaaaaaaaa0000000bbbbbbbb.... (выглядит неправильно)
sizeof
ваши типы иoffsetof
каждое из ваших полей, поможет вам отлаживать подобные вещи намного быстрее! :-) - person Cameron   schedule 30.10.2014