我有一个较旧的项目,它使用 fread() 将二进制文件读入结构。它使用 Visual Studio 2017 (v141)
我将项目升级到 VS 2019 的最新 C++ 工具版本 (v142),并将解决方案从 AnyCPU 更改为 x86。
我还将结构成员对齐方式从:1 字节 (/Zp1) 更改为:默认
因为这个错误:
错误 C2338 Windows 标头需要默认打包选项。更改此设置可能会导致内存损坏。可以通过定义 WINDOWS_IGNORE_PACKING_MISMATCH 来禁用此诊断。
但是现在数据不再被正确读取。
这是我用来读取二进制文件的代码:
FILE* RecipeFile;
short ReturnValue = 0; //AOK
if ((RecipeFile = fopen(rcpFile, "rb")) == NULL) {
ReturnValue = -1; //File open error
return(ReturnValue);
}
long sizeOfItem;
// obtain file size:
fseek(RecipeFile, 0, SEEK_END);
sizeOfItem = ftell(RecipeFile); // gives 771088
rewind(RecipeFile);
//sizeOfItem = sizeof(recipe); // gives 824304??
// now read the file contents:
int noOfItemsRead = fread(&recipe, sizeOfItem, 1, RecipeFile);
recipe
是一个结构。见下文。
我注意到这sizeof(recipe)
给出了与文件大小不同的结果。使用工具集 141,我得到 798276 字节。使用工具集 142,我得到 824304 字节。实际文件大小为 771088 字节。
这个问题真的是由结构成员对齐的变化引起的吗?
如何修复错误,以便再次正确读取文件?
编辑:我尝试将编译指示包指令添加到结构中,如下所示:
#pragma pack(push, 1)
struct tRecipe {
RMPTableDescriptorType O2Flow;
RMPTableDescriptorType HeFlow;
RMPTableDescriptorType SiCl4Flow;
RMPTableDescriptorType GeCl4Flow;
RMPTableDescriptorType Extra_Flow;
RMPTableDescriptorType POCl3Flow;
RMPTableDescriptorType C2F6Flow;
RMPTableDescriptorType SiF4Flow;
RMPTableDescriptorType Cl2Flow;
RMPTableDescriptorType BCl3Flow;
RMPTableDescriptorType TTC_Temp;
RMPTableDescriptorType TTC_H2Flow;
RMPTableDescriptorType TTC_Ratio;
RMPTableDescriptorType LCC_Speed;
RMPTableDescriptorType LSC_Speed;
RMPTableDescriptorType LTC_Speed;
RMPTableDescriptorType TDS_Cursor;
RMPTableDescriptorType TDC_Ctrl;
RMPTableDescriptorType TPC_Ctrl;
RMPTableDescriptorType TSS_Cursor;
DLUTableDescriptorType DLU;
EXHTableDescriptorType EXH;
GENTableDescriptorType GEN;
PARTableDescriptorType PAR;
REFTableDescriptorType REF;
SETTableDescriptorType SET;
SUPTableDescriptorType SUP;
TDCTableDescriptorType TDC;
TDSTableDescriptorType TDS;
TSSTableDescriptorType TSS;
TTCTableDescriptorType TTC;
TPCTableDescriptorType TPC;
};
#pragma pack(pop)
typedef struct
{
RParam Value;
UInt16 Duration;
OptType Opt;
#if DOS
int Unused16BitVar; /* Established to allow Win32 NT Code to use 32bit */
#endif
}
RMPElementDescriptorType;
/*-----------------------------------------------------------------------------*/
typedef struct
{
UInt16 StartNoOf;
UInt16 EndNoOf;
Char8 StartRampType;
Char8 EndRampType;
RMPElementDescriptorType RMPElementArray[RAMP_ELEM_NO_OF];
}
RMPRampDescriptorType;
/*-----------------------------------------------------------------------------*/
typedef struct
{
UInt16 SizeInfo;
Char8 DBPTxtInfo[DBP_TXT_NO_OF];
RMPRampDescriptorType RMPRampArray[RAMP_NO_OF];
}
RMPTableDescriptorType;
但它似乎对错误没有任何影响。