У меня есть вектор байтов, и я хочу преобразовать их в тип данных четверного слова (64-битный прямой порядок байтов).

Пример вектора в Dword (32 бит):

int DataConversor::toDword()
{
    return ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]));
}

Проблема смещается с более чем 32 байтами, ее поведение undefined в соответствии с Visual Studio 2013:

__int64 DataConversor::toQuadWord()
{
    return (__int64)((data[0] << 64 | data[1] << 56 | data[2] << 48 | data[3] << 40 |
        data[4] << 32 | data[5] << 24) | (data[6] << 16) | (data[7] << 8) | (data[8]));
}

Любой способ сделать это без использования директивы _ASM?

c++
3
ffenix 1 Сен 2014 в 07:22

3 ответа

Лучший ответ

Что ж, data[0] << 64, вероятно, случайность ...

Но data[0] << 56 - это не то, что вам нужно. Вы хотите static_cast<uint64_t>(data[0]) << 56. А затем это повторилось и на всех других операциях.

Следовательно, вы хотите, чтобы ваша функция выглядела примерно так:

int64_t DataConversor::toQuadWord() {
    uint64_t result = 0;
    result |= static_cast<uint64_t>(data[0]) << 56;
    result |= static_cast<uint64_t>(data[1]) << 48;
    result |= static_cast<uint64_t>(data[2]) << 40;
    result |= static_cast<uint64_t>(data[3]) << 32;
    result |= static_cast<uint64_t>(data[4]) << 24;
    result |= static_cast<uint64_t>(data[5]) << 16;
    result |= static_cast<uint64_t>(data[6]) << 8;
    result |= static_cast<uint64_t>(data[7]) << 0;
    return (int64_t) result;
}
4
Bill Lynch 1 Сен 2014 в 03:24

Нет независимого от компилятора способа. Вы можете использовать int64_t __builtin_bswap64 (int64_t x) в GCC и unsigned __int64 _byteswap_uint64(unsigned __int64 value) в MSVC, чтобы поменять местами порядок байтов. Вы можете использовать это, если ваш массив по определению везде имеет прямой порядок байтов (по крайней мере, это не изменит порядок байтов в других системах). Вы должны привести тип к 64-битному целому числу.

int64_t convertEndianess(uint8_t x[])
{
    return _byteswap_uint64(*static_cast<int64_t*>(x));
}
1
N00b 1 Сен 2014 в 03:28

С прямым порядком байтов и вы знаете, что байты упакованы, вы можете сделать

return *reinterpret_cast<int64_t*>(&data[0]) ;
-1
user3344003 1 Сен 2014 в 15:21