将一个结构体里面的数据转为 小端对齐的二进制流

现在有一个C++的结构体,需要把它转为二进制流,而且是小端对齐的。

我们还需要将一个小端对齐的二进制流,转为对应的结构体。

appendLittleEndian
parseLittleEndian

这2个方法是chatgpt提供给我的,功能能准确实现。代码也比较简洁。

 

#include <iostream>  
#include <vector>
#include <cstring>
#include <iomanip>

typedef struct tagInfoA {
    uint8_t    Ver;
    uint16_t   Code;
    uint8_t    Reserve;
    uint16_t   Length;
    uint16_t   AttrCount;

    uint32_t   a;
    uint32_t   b;
    int        c;
    char       szBuf1[10];
    char       szBuf2[10];
    int        d;
} INFOA_DEF;

bool isLittleEndian() {
    uint32_t num = 0x01020304;
    uint8_t* ptr = reinterpret_cast<uint8_t*>(&num);
    return (*ptr == 0x04); // If the least significant byte (LSB) is 0x04, then it's little-endian
}

void appendLittleEndian(std::vector<uint8_t>& block, const void* data, size_t size) {
    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
    for (size_t i = 0; i < size; ++i) {
        block.push_back(*ptr);
        ++ptr;
    }
}

template<typename T>
void parseLittleEndian(const std::vector<uint8_t>& block, size_t& offset, T& value) {
    std::memcpy(&value, &block[offset], sizeof(T));
    offset += sizeof(T);
}

int main() {  
    if (isLittleEndian()) {
        std::cout << "Current machine is little-endian.\n";
    } else {
        std::cout << "Current machine is big-endian.\n";
    }

    std::vector<uint8_t> block;
    INFOA_DEF test1;
    test1.Ver = 0x01;
    test1.Code = 0x0203;
    test1.Reserve = 0x04;
    test1.Length = 0x0506;
    test1.AttrCount = 0x0708;
    test1.a = 0x1234;
    test1.b = 0x5678;
    test1.c = 0xabcd;
    std::memcpy(test1.szBuf1, "12345", 6); // Copy only 6 characters to leave space for null terminator
    std::memcpy(test1.szBuf2, "abcdefg", 8); // Copy only 8 characters to leave space for null terminator
    test1.d = 400;

    // Convert struct to little-endian byte stream
    appendLittleEndian(block, &test1.Ver, sizeof(test1.Ver));
    appendLittleEndian(block, &test1.Code, sizeof(test1.Code));
    appendLittleEndian(block, &test1.Reserve, sizeof(test1.Reserve));
    appendLittleEndian(block, &test1.Length, sizeof(test1.Length));
    appendLittleEndian(block, &test1.AttrCount, sizeof(test1.AttrCount));
    appendLittleEndian(block, &test1.a, sizeof(test1.a));
    appendLittleEndian(block, &test1.b, sizeof(test1.b));
    appendLittleEndian(block, &test1.c, sizeof(test1.c));
    appendLittleEndian(block, test1.szBuf1, sizeof(test1.szBuf1));
    appendLittleEndian(block, test1.szBuf2, sizeof(test1.szBuf2));
    appendLittleEndian(block, &test1.d, sizeof(test1.d));

    // Output binary stream
    std::cout << "Binary Stream in little-endian format:\n";
    for (uint8_t byte : block) {
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
    }
    std::cout << std::endl;

    // Parse binary stream back to struct
    size_t offset = 0;
    INFOA_DEF parsedData;
    parseLittleEndian(block, offset, parsedData.Ver);
    parseLittleEndian(block, offset, parsedData.Code);
    parseLittleEndian(block, offset, parsedData.Reserve);
    parseLittleEndian(block, offset, parsedData.Length);
    parseLittleEndian(block, offset, parsedData.AttrCount);
    parseLittleEndian(block, offset, parsedData.a);
    parseLittleEndian(block, offset, parsedData.b);
    parseLittleEndian(block, offset, parsedData.c);
    std::memcpy(parsedData.szBuf1, &block[offset], sizeof(parsedData.szBuf1));
    offset += sizeof(parsedData.szBuf1);
    std::memcpy(parsedData.szBuf2, &block[offset], sizeof(parsedData.szBuf2));
    offset += sizeof(parsedData.szBuf2);
    parseLittleEndian(block, offset, parsedData.d);

    // Output parsed struct
    std::cout << "\nParsed Data:\n";
    std::cout << "Ver: " << std::hex << static_cast<int>(parsedData.Ver) << std::endl;
    std::cout << "Code: " << std::hex << static_cast<int>(parsedData.Code) << std::endl;
    std::cout << "Reserve: " << std::hex << static_cast<int>(parsedData.Reserve) << std::endl;
    std::cout << "Length: " << std::hex << static_cast<int>(parsedData.Length) << std::endl;
    std::cout << "AttrCount: " << std::hex << static_cast<int>(parsedData.AttrCount) << std::endl;
    std::cout << "a: " << std::hex << parsedData.a << std::endl;
    std::cout << "b: " << std::hex << parsedData.b << std::endl;
    std::cout << "c: " << std::hex << parsedData.c << std::endl;
    std::cout << "szBuf1: " << parsedData.szBuf1 << std::endl;
    std::cout << "szBuf2: " << parsedData.szBuf2 << std::endl;
    std::cout << "d: " << std::dec << parsedData.d << std::endl;

    return 0;  
}

 

打印的结果:

Current machine is little-endian.
Binary Stream in little-endian format:
01 03 02 04 06 05 08 07 34 12 00 00 78 56 00 00 cd ab 00 00 31 32 33 34 35 00 00 00 b0 30 61 62 63 64 65 66 67 00 40 00 90 01 00 00 

Parsed Data:
Ver: 1
Code: 203
Reserve: 4
Length: 506
AttrCount: 708
a: 1234
b: 5678
c: abcd
szBuf1: 12345
szBuf2: abcdefg
d: 400

 

posted @ 2024-04-08 23:02  He_LiangLiang  阅读(16)  评论(0编辑  收藏  举报