4

我正在尝试使用 boost::signal 来实现回调机制,并且我在 boost::signal 代码中获得了一个内存访问断言,即使是库的最琐碎的使用。我已将其简化为以下代码:

#include <boost/signal.hpp>

typedef boost::signal<void (void)> Event;

int main(int argc, char* argv[])
{

    Event e;

    return 0;
}

谢谢!

编辑:这是使用带有 SP1 的 Visual Studio 2008 编译的 Boost 1.36.0。Boost::filesystem,就像 boost::signal 一样,也有一个必须链接的库,它似乎工作正常。我相信,我使用的所有其他 boost 库都只有标头。

4

4 回答 4

6

我已经确认这是一个问题 - Microsoft 的 Stephan T Lavavej (STL!)对此发表了博文

具体来说,他说:

一般的问题是链接器没有诊断出所有的单一定义规则 (ODR) 违规。虽然并非不可能,但这是一个难以解决的问题,这就是为什么该标准特别允许某些 ODR 违规行为未被诊断出来。

我当然希望编译器和链接器有一种特殊的模式,可以在构建时捕获所有 ODR 违规,但我认识到这很难实现(并且会消耗可能会被更好地利用的资源,比如更多的一致性)。无论如何,通过适当地构造代码,无需付出极大的努力就可以避免 ODR 违规,因此我们作为程序员可以应对这种缺乏链接器检查的情况。

但是,通过打开和关闭来更改代码功能的宏正在危险地与 ODR 调情,具体的问题是 _SECURE_SCL 和 _HAS_ITERATOR_DEBUGGING 都是这样做的。乍一看,这似乎并没有那么糟糕,因为您应该已经可以控制在构建系统中在项目范围内定义了哪些宏。但是,单独编译的库会使事情复杂化——如果您(例如)使用 _SECURE_SCL 构建 Boost,这是默认设置,您的项目不得关闭 _SECURE_SCL。如果您打算在您的项目中关闭 _SECURE_SCL,现在您必须相应地重新构建 Boost。并且根据所讨论的单独编译的库,这可能很困难(根据我的理解,使用 Boost 可以做到,我只是从来没有弄清楚如何)。

他稍后在评论中列出了一些可能的解决方法,但没有一个看起来适合这种情况。其他人报告说在编译 boost 时可以通过在boost/config/compiler/visualc.hpp中插入一些定义来关闭这些标志,但这对我不起作用。但是,在tools/build/v2/user-config.jam中逐字插入以下行就可以了。请注意,空格对于提高 jam 很重要。

使用 msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ;
于 2008-09-29T17:01:09.533 回答
2

当使用不同的堆实现进行编译时,经常会出现这种问题。在 VS 中,可以要求将 CRT 链接到(作为静态库),或者作为动态库保留。

如果您使用的库在其链接堆上分配内存,并且您的程序尝试使用另一个堆释放它,那么您会遇到麻烦:要释放的对象不在已分配的对象列表中。

于 2008-09-26T09:17:13.597 回答
1

我已经在我的系统上测试了你的代码,它工作正常。我认为您的编译器与构建 Boost.Signals 库的编译器之间存在不匹配。尝试下载 Boost 源代码,并使用与构建代码相同的编译器来编译 Boost.Signals。

仅供参考,您使用的是什么编译器(和版本)?

于 2008-09-26T00:51:16.857 回答
1

布赖恩,我刚刚遇到了和你一模一样的问题。感谢您对博客文章的回答,我将其追踪到我们禁用_HAS_ITERATOR_DEBUGGINGand _SECURE_SCL

为了解决这个问题,我手动构建了 boost 库。我不需要弄乱配置文件。这是我使用的两个命令行:

x86
bjam 调试发布链接=静态线程=多运行时链接=共享定义=_SECURE_SCL=0 定义=_HAS_ITERATOR_DEBUGGING=0 --with-signals 阶段

x64
bjam 调试发布链接=静态线程=多运行时链接=共享定义=_SECURE_SCL=0 定义=_HAS_ITERATOR_DEBUGGING=0 地址模型=64 --with-signals 阶段

这将构建以下文件:
libboost_signals-vc90-mt-1_43.lib
libboost_signals-vc90-mt-gd-1_43.lib

希望有帮助。

于 2010-09-27T10:49:53.200 回答