Приведение / преобразование из size_t в uint8_t в C ++? - PullRequest
0 голосов
/ 19 октября 2011

Я пытаюсь написать код, использующий сокеты boost :: asio для отправки сообщения с одного конца (клиента) на другой (сервер).

Моя конкретная цель прямо сейчас состоит в том, чтобы добавить каждое отправляемое сообщение к 1-байтовому целому числу без знака (uint8_t), сообщающему получателю, сколько байтов занимает остальная часть сообщения.

Обратите внимание, что причина, по которой я сохраняю и передаю размер как uint8_t вместо size_t, заключается в том, что я хочу убедиться, что он будет ровно 1 байт на обеих машинах. Небольшое прибегание к поиску показало, что size_t может иметь разный размер на машине A и машине B, что может испортить ситуацию.

Итак, здесь я вычисляю длину сообщения. Сообщение состоит только из двух частей: uint16_t, за которым следует переменная «data», представляющая собой (void *) - отлитый фрагмент памяти, который будет служить различным целям (у целевой машины есть способы интерпретации этих данных, но я выиграл ' вот сюда))

uint8_t sizeOfMessage = sizeof(uint16_t) + sizeof(data);

В этом примере sizeof (data) == 4, поэтому sizeOfMessage должно равняться 6 (поскольку uint16_t является 2-байтовым целым числом). Однако, если я std :: cout << sizeOfMessage, то отображается не 6, а специальный символ: лопата (как в карточном масти). Глядя на данные в отладчике VS2010, они отображаются как <strong>6 '-' . Однако, если я определю sizeOfMessage как size_t и выведу его, все будет хорошо (но, конечно, я не могу отправить это по сети, потому что размер в байтах size_t не гарантируется от одной машины к другой).

Я полагаю, это означает, что что-то не так в том, как size_t преобразуется в uint8_t после арифметики. sizeof возвращает size_t, поэтому мой код добавляет два size_t и затем преобразует их в uint8_t.

Правильно ли я в своем заключении, что значение не приводится правильно? Если так, как я могу решить это?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 19 октября 2011

Значение, присваиваемое вашей маленькой переменной (uint8_t), не является печатаемым символьным кодом ASCII, который будет отображаться как «6».Вместо этого это двоичное значение, которое эквивалентно кодированию '\ 006' в вашем исходном коде.Если ваш протокол передачи данных работает с байтами двоичного кода, вы, вероятно, готовы.Что получает принимающая программа в своем экземпляре (uint8_t), в который она читает один байт (символ)?И, конечно, использование (uint8_t) ограничивает общую длину сообщения от 0 до 255 (но вы это знали).

0 голосов
/ 19 октября 2011

uint8_t обычно является typedef для типа char, и они перегружены для форматированного вывода для печати в виде символов, а не чисел. К сожалению, это одна из самых уродливых сторон ввода-вывода в формате C ++, так как вам придется преобразовать в целое число для вывода на печать:

char c;
unsigned char u;

std::cout << (unsigned int)(unsigned char)(c) << std::endl
          << (unsigned int)(u) << std::endl;
0 голосов
/ 19 октября 2011

uint8_t - это unsigned char в вашей системе, поэтому при выводе он записывает его как символ, а не как целое число, значение которого равно 6.

В вашем приведении нет ничего плохого.1005 *

...