Итак, я знаю, как определять порядок байтов программно.
Вопрос
Есть ли более стандартный или собственный (закрытый ящик) способ определения порядка следования байтов? предлагает ли WINAPI такое решение?
Итак, я знаю, как определять порядок байтов программно.
Есть ли более стандартный или собственный (закрытый ящик) способ определения порядка следования байтов? предлагает ли WINAPI такое решение?
ntohl()
и htonl()
при преобразовании данных, они знают, какой порядок байтов у машины 23.10.2014 Стандартная функциональность С++ для определения порядка байтов не предусмотрена. И я, и Беман Доус работаем над тем, чтобы это исправить. Однако успех в таком начинании будет как ледниковым, так и далеко не гарантированным.
Я экспериментировал со следующим заголовком:
https://github.com/HowardHinnant/hash_append/blob/master/endian.h
который, как показано, не переносим в Windows, но, безусловно, может быть легко перенесен в Windows разработчиком std::lib. Механизм очень прост:
// endian provides answers to the following questions:
// 1. Is this system big or little endian?
// 2. Is the "desired endian" of some class or function the same as the
// native endian?
enum class endian
{
native = // unspecified,
little = // unspecified,
big = // unspecified
};
Если вы работаете на машине с прямым порядком байтов, то endian::native == endian::little
.
Если вы работаете на машине с обратным порядком байтов, то endian::native == endian::big
.
Если вы работаете на машине со смешанным порядком следования байтов (я давно ее не видел), то endian::native
имеет значение, отличное от big
или little
.
Этот файл:
https://github.com/HowardHinnant/hash_append/blob/master/hash_append.h
показаны некоторые примеры использования этого объекта. Например, есть что-то, называемое Hasher
, которое может запросить, чтобы предоставленные ему скаляры были представлены в одной из трех форм:
И есть небольшая утилита, которая инвертирует (или нет) байты скаляра, в зависимости от пожеланий Hasher
и родного endian платформы:
template <class T>
constexpr
inline
void
reverse_bytes(T& t)
{
unsigned char* bytes = static_cast<unsigned char*>(std::memmove(std::addressof(t), std::addressof(t), sizeof(T)));
for (unsigned i = 0; i < sizeof(T)/2; ++i)
std::swap(bytes[i], bytes[sizeof(T)-1-i]);
}
template <class T>
constexpr
inline
void
maybe_reverse_bytes(T& t, std::true_type)
{
}
template <class T>
constexpr
inline
void
maybe_reverse_bytes(T& t, std::false_type)
{
reverse_bytes(t);
}
template <class T, class Hasher>
constexpr
inline
void
maybe_reverse_bytes(T& t, Hasher&)
{
maybe_reverse_bytes(t, std::integral_constant<bool,
Hasher::endian == endian::native>{});
}
constexpr
для платформ со статическим порядком байтов и неconstexpr
в противном случае? 24.10.2014EXC_BAD_INSTRUCTION
. Может быть, я попробую написать расширение ядра и посмотрю, что произойдет... 24.10.2014