如何使用__cdecl调用约定编译boost?

时间:2010-04-24 14:10:25

标签: visual-studio-2010 boost calling-convention stdcall cdecl

我有一个使用__cdecl调用约定(msvc2010)编译的项目,我使用默认设置使用相同的编译器编译了boost。

该项目与boost相关联,但我在运行时得到了这样的断言消息: 文件:... \ boost \ boost \ program_options \ detail \ parsers.hpp 行:79

运行时检查失败#0 - ESP的值未在函数调用中正确保存。这通常是调用使用一个调用约定声明的函数的结果,函数指针使用不同的调用约定声明。

有以下问题:

  • 默认情况下,Windows(msvc2010)
  • 上的调用约定会提升构建
  • 如何使用__cdecl调用约定来编译boost
  • 为什么boost无法阻止与具有不同调用约定的代码链接?我知道boost有非常智能的库自动包含代码。

更新#1

看起来boost会编译并链接正确的调用约定,仍然在运行时我遇到上述问题。我使用相同的代码做了一个示例应用程序,它可以工作,但在我的应用程序中失败了。唯一的区别可能来自项目配置或包含/ stdafx.h

3 个答案:

答案 0 :(得分:2)

只需使用

bjam ... **cxxflags=/Zp4**

在构建boost库时。

答案 1 :(得分:1)

据我所知,没有办法让C ++使用cdecl调用约定(参见MSDN Calling Convention)。 C ++方法调用与C不同。您必须使用其中一种C调用约定的唯一机会是函数,其中包括C ++中的类静态函数。如果您知道这种情况,您可以在构建期间通过添加选项来尝试强制选项:

bjam cxxflags = / Gd ...

(见BBv2 Builtin features

或者使其“永久”与您的编译器一起设置user-config.jam并将其添加到所有BBv2 msvc构建的构建选项中(请参阅BBv2 Configuration和相关文档)。至于你还有其他问题:

  1. Boost使用MSVC使用的默认调用约定,但在代码级别覆盖它的情况除外。我不知道它们在哪里,因为它们是特定于图书馆的。所以你必须在代码中搜索“__ *”代码装饰器。
  2. 见上文部分答案。
  3. 检测;有两个原因:我们可以合理地检测出多少不同的选项,因为它是不同可能变化的指数增长,因此我们将其限制在最重要的情况下。在调用约定的情况下,它实际上是不可能的,因为它可以在每个函数的基础上进行更改。

答案 2 :(得分:0)

我在其中一个共享属性文件中找到了问题的原因:<StructMemberAlignment>4Bytes</StructMemberAlignment>

如果我删除它,代码将起作用。不过,我不确定为什么会这样,如果不删除上面的代码(另一个库需要),我怎么能解决呢。

我添加了另一个关于boost and structure member alignment的问题。