Использование ntohl для структуры или объединения

#c #linux #endianness #uint32-t

#c #linux #порядковый номер #uint32-t

Вопрос:

ntohl принимает uint32_t . У меня есть сообщения со многими разными членами (типа uint32_t или uint16_t ). Возможно ли правильно передать весь полученный struct or union и преобразовать его в say uint32_t , а затем reinterpret_cast в my union or struct ?

Как я это делал, так это перечислял построчно каждого отдельного члена union or struct и передавал его в ntohl / s вот так msg.member = ntohl(msg.member); , но это громоздко!

Структуры данных целиком передаются из приложения C # .NET (Windows) в приложение Linux.

Когда я попытался,

 void* ptr = amp;msg;
uint32_t temp = (uint32_t)ptr;
  

Компилятор жалуется, что:

ошибка: приведение из ‘void *’ в ‘uint32_t’ теряет точность

Комментарии:

1. Ответ будет отличаться для объединений и структур в зависимости от количества и типов их членов.

2. Пример все равно не будет работать, поскольку вы не преобразуете структуру в a uint32_t (что будет работать только в том случае, если структура содержит один uint32_t элемент), а адрес структуры. Так что это приведет к полному мусору. То, что вы хотели, было uint32_t temp = *(uint32_t*)amp;msg , но, как уже было сказано, это будет работать только в том случае, если структура имеет только один элемент типа uint32_t .

3. Можете ли вы изменить приложение C #, чтобы изменить способ передачи данных?

Ответ №1:

Нет, вы не можете. Только в том случае, если ваша структура содержит только одну uint32_t переменную. Кроме того, вы должны использовать разные ntoh<X> функции в зависимости от разных размеров переменных.

Ответ №2:

Вы можете использовать буферы протокола Google.

Комментарии:

1. Не вижу, как это отвечает на вопрос. Буферы протокола полностью преобразуют данные в другой формат, не так ли? Это их работа и все … вам понадобится намного больше, чем «использовать буферы протокола», чтобы это было полезным ответом. Как, скажем, пример.

2. Он делает именно то, что нужно @0A0D: он обрабатывает сериализацию. Вместо того, чтобы вручную записывать и считывать поля одно за другим, что может быть громоздким, вы просто объявляете свою структуру в файле .proto, и протокол генерирует (высоко оптимизированный) код, который делает именно это.

3. Однако, если он случайно переносит структуру из существующего приложения, буферы протокола искажают данные до неузнаваемости. Ему нужно было бы переписать обе стороны, чтобы использовать буферы протокола вместо необработанных структур. И еще не было сказано, есть ли у него доступ или возможность сделать это.