gpt4 book ai didi

c++ - 结构包装重复

转载 作者:行者123 更新时间:2023-11-28 06:25:23 25 4
gpt4 key购买 nike

我正在写代码给 a specification它定义了没有打包的结构,例如:

struct LASHeader_1p2
{
char FileSig[4]; //= "LASF"; // 4
unsigned __int16 FileSource; // 2 6
unsigned __int16 Reserved_Unused; // 2 8
unsigned __int32 Project_ID_Data1; // 4 12
unsigned __int16 Project_ID_Data2; // 2 14
unsigned __int16 Project_ID_Data3; // 2 16
char Project_ID_Data4[8]; // 8 24
unsigned char Version_Major; // 1 25
unsigned char Version_Minor; // 1 26
char System_ID[32]; //32 58
char Software[32]; //32 90
unsigned __int16 FC_Day, FC_Year, Header_Size; // 2,2,2 96
unsigned __int32 Offset_to_Data; // 4 100 0x60
unsigned __int32 VarLenRecs; // 4 104 0x64
unsigned char Pt_DataFormat; // 1 105 0x65
unsigned __int16 Pt_DataRecLen; // 2 107 0x68
unsigned __int32 PointCount; // 4 111 0x6A
unsigned __int32 Point_by_Return_0; // 4 115
unsigned __int32 Point_by_Return_1; // 4 119
unsigned __int32 Point_by_Return_2; // 4 123
unsigned __int32 Point_by_Return_3; // 4 127
unsigned __int32 Point_by_Return_4; // 4 131
double Xscale; // 8 139
double Yscale; // 8 147
double Zscale; // 8 155
double Xoffset; // 8 163
double Yoffset; // 8 171
double Zoffset; // 8 179
double MaxX; // 8 187
double MinX; // 8 195
double MaxY; // 8 203
double MinY; // 8 211
double MaxZ; // 8 219
double MinZ; // 8 227
};

围绕 unsigned char Pt_DataFormat; 结构与默认值(4 字节)不对齐。为了弥补这一点,我使用/Zp1 编译器选项来使用没有填充/对齐的结构。虽然这可能会更慢,但它允许我读取字节并将其解释为结构:

char* buffer = (char*)malloc(sizeof(LASHeader_1p2));
pReadStream.read(buffer ,sizeof(LASHeader_1p2));
LASHeader_1p2* Header = (LASHeader_1p2*)buffer;

我可以修改值,然后以字节形式写入文件。唯一的其他选择是将结构分成多个部分,这些部分将对齐并读取单个字节,这对我来说似乎有点狡猾。

但是其他库不喜欢/Zp1,我怀疑它们包含内部填充的结构,这些结构在未填充时不再运行。

我一直在看pragma pack__declspec(align())但我不确定哪个合适以及如何使用它们。

任何人都可以阐明如何继续,在没有填充的情况下读取和转换结构,但为需要它的其他库维护填充吗?

最佳答案

对于 Visual Studio,您希望将您的结构包围在:

#pragma pack(push, 1) //Save packing value and set to 1 byte
<struct definition>
#pragma pack(pop) //Reset to whatever the packing was before.

所以,这个:

#include <iostream>

#pragma pack(push, 1)
struct packed
{
char FileSig[4]; //= "LASF"; // 4
unsigned __int16 FileSource; // 2 6
unsigned __int16 Reserved_Unused; // 2 8
unsigned __int32 Project_ID_Data1; // 4 12
unsigned __int16 Project_ID_Data2; // 2 14
unsigned __int16 Project_ID_Data3; // 2 16
char Project_ID_Data4[8]; // 8 24
unsigned char Version_Major; // 1 25
unsigned char Version_Minor; // 1 26
char System_ID[32]; //32 58
char Software[32]; //32 90
unsigned __int16 FC_Day, FC_Year, Header_Size; // 2,2,2 96
unsigned __int32 Offset_to_Data; // 4 100 0x60
unsigned __int32 VarLenRecs; // 4 104 0x64
unsigned char Pt_DataFormat; // 1 105 0x65
unsigned __int16 Pt_DataRecLen; // 2 107 0x68
unsigned __int32 PointCount; // 4 111 0x6A
unsigned __int32 Point_by_Return_0; // 4 115
unsigned __int32 Point_by_Return_1; // 4 119
unsigned __int32 Point_by_Return_2; // 4 123
unsigned __int32 Point_by_Return_3; // 4 127
unsigned __int32 Point_by_Return_4; // 4 131
double Xscale; // 8 139
double Yscale; // 8 147
double Zscale; // 8 155
double Xoffset; // 8 163
double Yoffset; // 8 171
double Zoffset; // 8 179
double MaxX; // 8 187
double MinX; // 8 195
double MaxY; // 8 203
double MinY; // 8 211
double MaxZ; // 8 219
double MinZ; // 8 227
};
#pragma pack(pop)

struct unpacked
{
char FileSig[4]; //= "LASF"; // 4
unsigned __int16 FileSource; // 2 6
unsigned __int16 Reserved_Unused; // 2 8
unsigned __int32 Project_ID_Data1; // 4 12
unsigned __int16 Project_ID_Data2; // 2 14
unsigned __int16 Project_ID_Data3; // 2 16
char Project_ID_Data4[8]; // 8 24
unsigned char Version_Major; // 1 25
unsigned char Version_Minor; // 1 26
char System_ID[32]; //32 58
char Software[32]; //32 90
unsigned __int16 FC_Day, FC_Year, Header_Size; // 2,2,2 96
unsigned __int32 Offset_to_Data; // 4 100 0x60
unsigned __int32 VarLenRecs; // 4 104 0x64
unsigned char Pt_DataFormat; // 1 105 0x65
unsigned __int16 Pt_DataRecLen; // 2 107 0x68
unsigned __int32 PointCount; // 4 111 0x6A
unsigned __int32 Point_by_Return_0; // 4 115
unsigned __int32 Point_by_Return_1; // 4 119
unsigned __int32 Point_by_Return_2; // 4 123
unsigned __int32 Point_by_Return_3; // 4 127
unsigned __int32 Point_by_Return_4; // 4 131
double Xscale; // 8 139
double Yscale; // 8 147
double Zscale; // 8 155
double Xoffset; // 8 163
double Yoffset; // 8 171
double Zoffset; // 8 179
double MaxX; // 8 187
double MinX; // 8 195
double MaxY; // 8 203
double MinY; // 8 211
double MaxZ; // 8 219
double MinZ; // 8 227
};


int main()
{
std::cout << "sizeof(packed) = " << sizeof(packed) << "\n";
std::cout << "sizeof(unpacked) = " << sizeof(unpacked) << "\n";
return 0;
}

输出

sizeof(packed)   = 227
sizeof(unpacked) = 232

如果你愿意,你甚至可以嵌套它们并给不同的级别命名,但我很少这样做。文档是 here .

关于c++ - 结构包装重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28622116/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com