应用程序和 exe 之间的类大小变化
Class size change between application and exe
我有一个实例化类的控制台应用程序(比如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
语句,并验证它们始终正确设置和取消设置(如果您有没有弹出的推送,那么您可能会遇到错误(。
该类在两个项目上具有相同的对齐方式?
如果你在你的类中没有发现问题,也许问题出在它继承的类/结构之一中,或者它作为成员变量。
因此,验证它们,就像验证主类一样。
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- C++取消引用指针.为什么会发生变化
- 为什么在读取文件大小时文件IO速度会发生变化
- 终端不会为C++文件创建.exe文件吗
- 在Windows中以.exe的形式运行c++
- Visual Studio mkl_link_tool.exe链接错误
- 为什么cudaMemGetInfo报告设备内存总量的变化
- PrintWindow函数在notepad.exe中出错
- 如何避免LED在循环状态变化中闪烁?
- 当 I2C 值在C++中发生变化时收到通知
- VSCode C++ 编译的exe感染了Win32:TrojanX-gen[Trj]
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- Gtkmm 会不断检查 Gtk::日历上的所选日期是否发生变化
- 获取当前正在运行的 exe 名称(不是路径)
- 当我调用对象的方法时,对象的成员会发生变化
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- 为什么向量内部的指针在从函数返回时会发生变化?
- 1d.exe找不到SFML文件?
- 应用程序和 exe 之间的类大小变化
- 防止.exe的时间戳发生变化