我正在 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(); };
对于下一个目标文件,编译器关于 f() 在类的 vtable 中的位置的假设是不正确的。
通常简单地重新编译世界(一切!)会有所帮助。
这很可能是由于调用约定不兼容,库和调用者对堆栈布局有不同的想法。
查看MSDN了解更多信息。
确保您没有在项目中选择旧版本的库,即(正如 Adam 提到的)您选择了旧的调试版本而不是当前的发布版本,反之亦然。
你可能需要重建。
还要注意条件编译,其中宏可能会在某些时候得到#defined 或#undef'd(另一种解决方案可能有一些宏或投影的#defines)。有时,删除 .lib .obj 和预编译的标头缓存以及重建可能会有所帮助。
在您的 IDE 或项目配置中出现问题的可能性很小,您可能需要从头开始重新创建项目。
我对 MS VC 不太熟悉,您可以从其他解决方案添加库的项目文件吗?例如,在 Borland C++ Builder 中,您可以定义项目组并构建/制作多个项目,我总是将我使用的库的项目放在我的程序项目组中,以便在我构建时一切都是最新的。
确保您在调试模式而不是发布模式下编译。如果您尝试在 Release 模式下调试程序,由于优化,您从调试器返回的数据将是垃圾。
我记得当二进制文件的结构成员对齐(/Zp 编译器开关)不同时看到这样的事情。你也可以检查一下。
通过#pragma pack 设置它而不是通过项目设置应该更安全。