Есть ли какая-либо “стандартная” подобная htonl функция для целых чисел на 64 бита в C++?

Я работаю над реализацией протокола кэш-памяти, который, в некоторых точках, использует целочисленные значения на 64 бита. Эти значения должны быть сохранены в "сетевом порядке байтов".

Мне жаль, что не было некоторых uint64_t htonll(uint64_t value) функция, чтобы сделать изменение, но к сожалению, если это существует, я не мог бы найти его.

Таким образом, у меня есть 1 или 2 вопроса:

  • Действительно ли там кто-либо портативен (Windows, Linux, AIX) стандартная функция, чтобы сделать это?
  • Если бы нет такой функции, как Вы реализовали бы его?

Я имею в виду базовое внедрение, но я не знаю, как проверить порядок байтов во время компиляции для создания кода портативным. Таким образом, Ваша справка является больше, чем приветствие здесь ;)

Спасибо.


Вот конечное решение, которое я записал благодаря решению Brian.

uint64_t htonll(uint64_t value)
{
    // The answer is 42
    static const int num = 42;

    // Check the endianness
    if (*reinterpret_cast<const char*>(&num) == num)
    {
        const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
        const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t>(low_part) << 32) | high_part;
    } else
    {
        return value;
    }
}
60
задан ereOn 11 June 2010 в 13:15
поделиться

2 ответа

Вы, вероятно, ищете bswap_64 Я думаю, что он поддерживается практически везде, но я бы не назвал его стандартным.

Вы можете легко проверить эндианальность, создав int со значением 1, приведя адрес вашего int как char* и проверив значение первого байта.

Например:

int num = 42;
if(*(char *)&num == 42)
{
   //Little Endian
}
else
{
   //Big Endian
} 

Зная это, вы также можете сделать простую функцию, которая выполняет обмен.


Вы также всегда можете использовать boost, который содержит макросы endian, переносимые на разные платформы.

16
ответ дан 24 November 2019 в 17:55
поделиться

РЕДАКТИРОВАТЬ: объединение двух (используется код Брайана):

uint64_t htonll(uint64_t value)
{
     int num = 42;
     if(*(char *)&num == 42)
          return (htonl(value & 0xFFFFFFFF) << 32LL) | htonl(value >> 32);
     else 
          return value;
}

Предупреждение: непроверенный код! Пожалуйста, проверьте перед использованием.

-3
ответ дан 24 November 2019 в 17:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: