Как извлечь отдельные поля из массива байтов (который находится в BIG-ENDIAN) в С++

Я пытаюсь прочитать пару байтов из byteData, как указано ниже в моем коде на С++. Фактическое значение в byteData представляет собой двоичный байтовый массив байтов в формате байтового байта BIG-ENDIAN. Поэтому я просто не могу просто "отличить" массив байтов от строки.

byteData массив байтов состоит из этих трех вещей -

First is `schemaId` which is of two bytes (short datatype in Java)
Second is `lastModifiedDate` which is of eight bytes (long datatype in Java)
Third is the length of actual `byteArray` within `byteData` which we need from `byteData`.
Fourth is the actual value of that `byteArray` in `byteData`.

Теперь я пытаюсь извлечь вышеуказанную конкретную информацию из byteData в С++... Как-то я могу извлечь schemaId, но значение, которое идет, неверно. И я не уверен, как извлечь другие вещи от него...

uint16_t schemaId;
uint64_t lastModifiedDate;
uint16_t attributeLength;
const char* actual_binary_value;

while (result.next()) {
    for (size_t i = 0; i < result.column_count(); ++i) {
        cql::cql_byte_t* byteData = NULL;
        cql::cql_int_t size = 0;
        result.get_data(i, &byteData, size);

        if (!flag) {

            // I cannot just "cast" the byte array into a String
            // value = reinterpret_cast<char*>(byteData);

            // now how to retrieve schemaId, lastModifiedDate and actual_binary_value from byteData?

            schemaId = *reinterpret_cast<uint16_t*>(byteData);

            flag = false;
        }
    }

// this prints out 65407 somehow but it should be printing out 32767
    cout<< schemaId <<endl;
}

Если кто-то должен увидеть мой java-код, тогда это мой код java -

    byte[] avroBinaryValue = text.getBytes();

    long lastModifiedDate = 1289811105109L;
    short schemaId = 32767;

    int size = 2 + 8 + 4 + avroBinaryValue.length; // short is 2 bytes, long 8 and int 4

    ByteBuffer bbuf = ByteBuffer.allocate(size); 
    bbuf.order(ByteOrder.BIG_ENDIAN);

    bbuf.putShort(schemaId);
    bbuf.putLong(lastModifiedDate);
    bbuf.putInt(avroBinaryValue.length);
    bbuf.put(avroBinaryValue);

    // merge everything into one bytearray.
    byte[] bytesToStore = bbuf.array();

            Hex.encodeHexString(bytesToStore)

Может ли кто-нибудь помочь мне в том, что я неправильно делаю в своем коде на С++ и почему я не могу правильно извлечь из него и других полей schemaId?

Обновление: -

После использования этого -

schemaId = ntohs(*reinterpret_cast<uint16_t*>(data));

Я начал правильно возвращать значение для schemaId.

Но теперь, как извлечь другие вещи, такие как lastModifiedDate, длина фактического byteArray within byteData and actual value of that byteArray in byteData`.

Я использовал это для lastModifiedDate, но это не работает -

std::copy(reinterpret_cast<uint8_t*>(byteData + 2), reinterpret_cast<uint8_t*>(byteData + 10), lastModifiedDate);

Ответ 1

32767 равен 0x7fff. 65407 - 0xff7f. Обратите внимание, что байты верхнего и младшего порядка меняются местами. Вам нужно поменять эти байты, чтобы восстановить номер до исходного значения. К счастью, есть макрос или функция под названием ntohs (сеть для размещения коротких), которая делает именно то, что вы хотите. Является ли это макросом или функцией, и в каком заголовке он определен, зависит от вашей системы. Но имя макроса/функции всегда ntohs, независимо от того, используете ли вы Windows, Linux, Sun или Mac.

На маленькой конечной машине этот макрос или функция заменяет два байта, которые образуют 16-битное целое число. На большой конечной машине этот макрос/функция ничего не делает (это именно то, что требуется). Обратите внимание, что большинство домашних компьютеров в настоящее время мало ориентированы.