0

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

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

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

有以下问题:

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

更新#1

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

4

3 回答 3

2

只需使用

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

在构建boost库时。

于 2011-09-09T08:20:01.370 回答
1

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

bjam cxxflags=/Gd ...

(参见BBv2 内置功能

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

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

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

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

我添加了另一个关于boost 和结构成员对齐的问题。

于 2010-04-25T19:29:39.247 回答