我正在使用VS2008编译一个C++静态库,在解决方案中也有一个启动项目,它使用该库,而且运行良好。
但是,在另一个解决方案中使用该库时,出现了运行时检查失败的问题。 “ESP的值在函数调用跨度过程中没有得到正确保存。” 通过代码逐步执行,我发现函数foo()在崩溃之前会跳转到bar()。所涉及的函数只是常规函数,没有函数指针。
有人知道可能发生了什么问题,以及为什么在使用相同解决方案下的库时会正常工作吗?
编辑:这些函数(方法)是类的一部分,如果这有助于解决问题。
我正在使用VS2008编译一个C++静态库,在解决方案中也有一个启动项目,它使用该库,而且运行良好。
但是,在另一个解决方案中使用该库时,出现了运行时检查失败的问题。 “ESP的值在函数调用跨度过程中没有得到正确保存。” 通过代码逐步执行,我发现函数foo()在崩溃之前会跳转到bar()。所涉及的函数只是常规函数,没有函数指针。
有人知道可能发生了什么问题,以及为什么在使用相同解决方案下的库时会正常工作吗?
编辑:这些函数(方法)是类的一部分,如果这有助于解决问题。
请原谅我在这里阐述显而易见的事情,但是......当对象(.o)和头文件(.h)不同步时,我已经看到过很多次出现这种情况。特别是涉及虚拟方法时。
考虑以下情况:对象文件是使用头文件编译的:
class Foo { virtual void f(); };
但是然后头部被更改为:
class Foo { virtual void g(); virtual void f(); };
对于下一个目标文件,编译器对类的vtable中f()所在位置的假设是不正确的。
通常情况下,重新编译所有内容会有所帮助。
这很可能是由于不兼容的调用约定引起的,即库和调用者对堆栈布局有不同的想法。
请查看MSDN获取更多信息。
请确保你在项目中选择的不是旧版本的库,例如(如Adam所提到的),你选择了一个较旧的调试版本而不是当前发布版本或反之亦然。
您可能需要重新构建。
还要注意条件编译,其中宏可能会在某个时刻被#定义或#undef'd(另一种解决方案可能具有某些宏或预定义)。有时删除.lib .obj和预编译头缓存并进行重建可能会有所帮助。
有可能是IDE或项目配置出了问题,您可能需要从头开始重新创建项目。
我对MS VC不是很熟悉,您能否添加另一个解决方案中的库项目文件?例如,在Borland C++ Builder中,您可以定义项目组并构建/制作多个项目,我总是将我使用的库的项目放在我的程序项目组中,这样在构建时所有内容都会得到更新。
请确保您在调试时编译的是Debug模式而不是Release模式。如果您尝试在Release模式下调试程序,由于优化的原因,从调试器中获取的数据将会是垃圾。
我记得在二进制文件的结构成员对齐(/Zp编译器开关)不同时会出现这样的情况。你也可以检查一下。
通过#pragma pack设置而不是通过项目设置设置应该更安全。