15

我正在 vs2008 中编译一个 c++ 静态库,在解决方案中我还有一个使用该库的启动项目,并且工作正常。

但是当在另一个解决方案中使用该库时,我会遇到运行时检查失败。“ESP 的值没有在函数调用中正确保存” 单步执行代码时,我注意到函数 foo() 在崩溃之前跳转到 bar()。有问题的函数只是常规函数,没有函数指针。

任何人都有任何线索可能会发生什么,以及为什么在使用同一解决方案中的库时它会起作用?

编辑:函数(方法)是类的一部分,如果有帮助的话。

4

5 回答 5

16

请原谅我在这里说明了明显的流血,但是......我已经看到这种事情发生过很多次,当对象(.o)和头(.h)文件不同步时。特别是关于虚拟方法。

考虑:目标文件是用头文件编译的:

class Foo { virtual void f(); };

但随后标题更改为:

class Foo { virtual void g(); virtual void f(); };

对于下一个目标文件,编译器关于 f() 在类的 vtable 中的位置的假设是不正确的。

通常简单地重新编译世界(一切!)会有所帮助。

于 2008-12-16T01:05:33.830 回答
7

这很可能是由于调用约定不兼容,库和调用者对堆栈布局有不同的想法。

查看MSDN了解更多信息。

于 2008-12-15T13:06:21.130 回答
3
  • 确保您没有在项目中选择旧版本的库,即(正如 Adam 提到的)您选择了旧的调试版本而不是当前的发布版本,反之亦然。

  • 你可能需要重建。

  • 还要注意条件编译,其中宏可能会在某些时候得到#defined 或#undef'd(另一种解决方案可能有一些宏或投影的#defines)。有时,删除 .lib .obj 和预编译的标头缓存以及重建可能会有所帮助。

  • 在您的 IDE 或项目配置中出现问题的可能性很小,您可能需要从头开始重新创建项目。

  • 我对 MS VC 不太熟悉,您可以从其他解决方案添加库的项目文件吗?例如,在 Borland C++ Builder 中,您可以定义项目组并构建/制作多个项目,我总是将我使用的库的项目放在我的程序项目组中,以便在我构建时一切都是最新的。

于 2008-12-16T05:15:43.123 回答
2

确保您在调试模式而不是发布模式下编译。如果您尝试在 Release 模式下调试程序,由于优化,您从调试器返回的数据将是垃圾。

于 2008-12-15T12:48:43.270 回答
1

我记得当二进制文件的结构成员对齐(/Zp 编译器开关)不同时看到这样的事情。你也可以检查一下。

通过#pragma pack 设置它而不是通过项目设置应该更安全。

于 2008-12-15T13:10:04.320 回答