我有一个控制台应用程序来实例化一个类(比如class X
)。该类在dll中定义 - > X.dll。当我在应用程序中打印类的大小和类的一个函数(在应用程序调用它时调用它)时 - 我注意到大小的变化。
我正在使用VS 2010,应用程序打印类大小为6304,函数打印为6352.我在Release | Win32模式下编译了exe和dll。两者都定义了WIN32
和_WINDOWS
。但是没有定义WIN64
。
我注意到的更多是当我在exe中打印sizeof(time_t)
时,它打印4并且dll中的函数打印8.认为这可能是个问题。
我知道应该在哪里检查?
答案 0 :(得分:7)
我同意,如果DLL和EXE 在数据类型布局 上存在分歧,则可能会出现问题。
但是,除了您必须在两个项目之间使用 不同的项目设置 之外,我看不到任何其他解释。
为了找到罪魁祸首, 在解决方案中标记两个项目 ( Ctrl +左键单击),然后打开属性对话框。该对话框现在仅显示所选配置中两个项目的 属性 。尽管对话框乍一看似乎是模态对话,但您可以单击其中一个项目以仅查看其属性,还可以再次标记它们,这样您就可以 切换回来在这些观点之间 。到目前为止,我经常发现使用这种技术的问题。
如果此操作失败,您始终可以 比较项目文件 。他们是非常健谈的XML文件使得这更难。
答案 1 :(得分:2)
我已经不得不处理同一类的不同大小。
这最多导致崩溃(因为你的代码会尝试读取/写入超出类的实际数据),最坏的情况是奇怪的错误(比如将成员变量的值设置为42,然后读取它看到的值是1376256或类似的东西。)
原因通常与对齐问题有关。
这是你可以做的,看看你的问题是否是对齐问题:
在课程定义之前(或之后),添加以下行:
#pragma pack(show)
在编译输出中,您应该看到类似的内容:
1>。\ test_align.cpp(59):警告C4810:pragma pack的值(显示)== 8
这将显示编译头时的对齐方式。每次标题包含在CPP文件中时都会出现这种情况。在DLL编译和EXE编译中,该值始终是相同的。
如果它们不同,甚至一次,那么你就会出现错位问题......
也许你的DLL的默认结构对齐设置为1,而EXE有另一个值。 请检查项目的两个属性: “C / C ++”部分,“代码生成”小节,属性“Struct Member Alignment”。
要使一切正常工作,两个项目都应具有相同的值。
如果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
语句,并验证它们是否始终正确设置和取消设置(如果你有一个没有弹出的推送,那么你可能有错误。)
如果你没有在你的类中发现问题,那么问题可能在于它继承的类/结构之一,或者它具有成员变量。
所以验证它们,就像验证主类一样。
答案 2 :(得分:2)
在VS 2010中,time_t
类型应为64位值(构建目标是32位还是64位)。这可以通过定义_USE_32BIT_TIME_T
来覆盖32位目标构建 - 因此您应确保未在应用程序构建中定义(或者如果需要在那里定义,则还需要定义它适用于您的DLL或在DLL类定义中使用__time32_t
类型。
我还要确保您没有为DLL和应用程序构建设置不同的打包选项(请注意,可以在写得不好的头文件中更改打包配置)。在构建日志中查找/Zp
编译器选项和/或头文件中的#pragma pack
行,而没有重置为默认设置的相应#pragma pack()
。