将一个结构体里面的数据转为 小端对齐的二进制流
现在有一个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