#c #ios #endianness
#c #iOS #порядковый номер
Вопрос:
Я использую двоичный безопасный метод сериализации для передачи данных между клиентом и сервером. И оба они гарантированно будут строчными в конце.
Вместо преобразования int64_t
значения в символьную строку, безопасно ли переосмысливать его как двоичную строку для транспортировки … затем обратно в int64_t
по прибытии?
на клиенте..
int64_t timeValue = 1554532128;
std::basic_string<char> timeString((const char *)timeValue, sizeof(int64_t));
а затем на сервере..
std::basic_string<char> timeString;
int64_t timeValue = (int64_t)(*timeString.data());
Комментарии:
1. Вместо
std::basic_string<char>
я бы предпочел использоватьstd::vector<uint8_t>
илиstd::array<uint8_t,8>
, но с тем же порядком окончания его должно быть безопасно использовать для транспортировки.2. Безопасно это или нет, зависит от того, как вы отправляете строку и строите строку из полученных данных.
3. Я думаю, что это неправильно
int64_t timeValue = (int64_t)(*timeString.data());
, лучшеint64_t timeValue = *(int64_t*)(timeString.data());
4. Я использую grpc для связи двух процессов, и иногда, когда мне нужно отправить структуру, и я не хочу определять ее в прототипе (или это может быть одна из нескольких возможных структур, которые четко определены как POD), я использую этот метод. Я просто устанавливаю строковый параметр и создаю его именно таким образом. Следует позаботиться о создании строк с данными и размером , а не просто передавать
char*
. Тем не менее, я также обязательно проверяю этоsizeof(expected_struct) == str.size()
на принимающей стороне (вы должны сделатьsizeof(int64_t) == timeString.size()
, чтобы знать, что с вами все в порядке).
Ответ №1:
Безопасно использовать char*
указатель для доступа к необработанным байтам переменной, стандарт C предусматривает такое использование. Но вы неправильно преобразуете свои значения с обеих сторон. Вместо этого код должен выглядеть примерно так:
int64_t timeValue = ...;
std::string timeString(reinterpret_cast<char*>(amp;timeValue), sizeof(int64_t));
std::string timeString = ...;
//assert(timeString.size() == sizeof(int64_t));
int64_t timeValue = *reinterpret_cast<int64_t*>(timeString.data());