【问题标题】:How do I compile boost using __cdecl calling convention?如何使用 __cdecl 调用约定编译 boost?
【发布时间】:2010-04-24 14:10:24
【问题描述】:

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

项目与 boost 相关联,但我在运行时收到如下断言消息: 文件:...\boost\boost\program_options\detail\parsers.hpp 线路:79

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

有以下问题:

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

更新 #1

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

【问题讨论】:

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


    【解决方案1】:

    随便用

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

    在构建 boost 库时。

    【讨论】:

      【解决方案2】:

      据我所知,没有办法让 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. 检测;有两个原因: 我们可以合理地检测到用于构建的不同选项的数量是有限的,因为它是不同可能变化的指数增长,因此我们将其限制在最重要的情况下。在调用约定的情况下,这实际上是不可能的,因为它可以根据每个函数进行更改。

      【讨论】:

        【解决方案3】:

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

        如果我删除它,代码将起作用。不过,我不确定为什么会发生这种情况,以及如何在不删除上述代码的情况下解决它(这是另一个库所要求的)。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多