应用程序和 exe 之间的类大小变化

Class size change between application and exe

本文关键字:变化 exe 之间 应用程序      更新时间:2023-10-16

我有一个实例化类的控制台应用程序(比如class X(。该类在 dll -> X.dll 中定义。 当我在应用程序和类的一个函数中打印类的大小时(当应用程序调用它时被调用( - 我注意到大小变化。

我正在使用VS 2010,应用程序将类大小打印为6304,函数将其打印为6352。我已经在发布|Win32 模式。两者都定义了WIN32_WINDOWS。但没有定义WIN64

我注意到更多的是,当我在 exe 中打印sizeof(time_t)时,它会打印 4,dll 中的函数打印 8。认为这可能是一个问题。

知道我应该在哪里检查吗?

我同意如果 DLL 和 EXE 在数据类型的布局上存在分歧,这可能是一个问题。

但是,除了您必须在两个项目之间使用不同的项目设置之外,我看不到任何其他解释。

为了找到罪魁祸首,请在解决方案中标记两个项目(Ctrl +左键单击(,然后打开属性对话框。该对话框现在将仅显示所选配置中两个项目相同的属性。尽管乍一看对话框似乎是模态对话框,但您可以单击其中一个项目以仅查看其属性,也可以再次标记它们,以便您可以在这些视图之间来回切换。到目前为止,我通常使用这种技术发现问题。

如果此操作失败,则始终可以比较项目文件。不过,它们是相当健谈的XML文件,这使得这更加困难。

在 VS 2010 中,time_t 类型应为 64 位值(无论构建目标是 32 位还是 64 位(。 对于 32 位目标生成,可以通过定义_USE_32BIT_TIME_T重写这一点 - 因此应确保未在应用程序生成中定义该内容(或者,如果需要在此处定义,则还需要为 DLL 定义它或在 DLL 类定义中使用__time32_t类型(。

我还要确保您没有为 DLL 和应用程序构建设置不同的打包选项(请注意,可以在编写不佳的头文件中更改打包配置(。在构建日志和/或头文件中查找#pragma pack /Zp编译器选项,而不使用重置为默认设置的相应#pragma pack()

对齐问题?

我已经不得不处理同一类的如此不同大小的问题。

这充其量会导致崩溃(因为您的代码将尝试读取/写入超出类的实际数据(,最坏的情况是导致奇怪的错误(例如将成员变量的值设置为 42,然后读取它以查看值是 1376256 或类似的东西(。

原因通常与对齐问题有关。

您可以执行以下操作来查看您的问题是否是对齐问题:

在类定义之前(或之后(,添加以下行:

#pragma pack(show)

在编译输出中,您应该看到类似以下内容:

1>.\test_align.cpp(59(:警告 C4810:编译指示包的值(显示(== 8

这将在编译标头时显示对齐方式。每次标头包含在 CPP 文件中时,都会显示此消息。在 DLL 编译和 EXE 编译中,此值应始终相同。

如果它们不同,即使是一次,那么你就有错位问题......

项目的默认结构对齐

也许您的 DLL 的默认结构对齐方式设置为 1,而 EXE 具有另一个值。请检查项目的两个属性:"C/C++"部分,"代码生成"小节,属性"结构成员对齐"。

为了使一切正常工作,两个项目应具有相同的值。

如果 EXE 和 DLL 具有不同的值,则必须更正该值("默认"值通常是好的值:"从父值或项目值继承"(。

杂货包?

还有另一种方法可以打破对齐方式,即通过使用#pragma pack语句。例如:

#pragma pack(show) // this will show the default value, i.e. 8 on my project
struct Data8       // the sizeof this struct is 8 bytes
{
   bool     m_bValue ;
   int      m_iValue ;
} ;
#pragma pack(push, 1)
#pragma pack(show) // this will show the now current value, i.e. 1
struct Data1       // the sizeof this struct is 5 bytes, thanks to the packing
{
   bool     m_bValue ;
   int      m_iValue ;
} ;
#pragma pack(pop)
#pragma pack(show) // this will show again the default value, i.e. 8

因此,搜索#pragma pack语句,并验证它们始终正确设置和取消设置(如果您有没有弹出的推送,那么您可能会遇到错误(。

该类在两个项目上具有相同的对齐方式?

如果你在你的类中没有发现问题,也许问题出在它继承的类/结构之一中,或者它作为成员变量。

因此,验证

它们,就像验证主类一样。