我正在尝试使用boost :: signal来实现一个回调机制,即使是最简单的库使用,我也会在boost :: signal代码中获得内存访问断言。我把它简化为这段代码:
#include <boost/signal.hpp>
typedef boost::signal<void (void)> Event;
int main(int argc, char* argv[])
{
Event e;
return 0;
}
谢谢!
编辑:这是使用Visual Studio 2008 w / SP1编译的Boost 1.36.0。 Boost :: filesystem,像boost :: signal也有一个必须链接的库,它似乎工作正常。我相信,我使用的所有其他升级库都只是标题。
答案 0 :(得分:6)
我已经确认这是一个问题 - 微软blogged about this的Stephan T Lavavej(STL!)。
具体来说,他说:
一般问题是链接器不会诊断所有一个定义规则(ODR)违规。虽然并非不可能,但这是一个难以解决的问题,这就是为什么标准特别允许某些ODR违规未被诊断的原因。
我当然希望编译器和链接器能够在构建时捕获所有ODR违规的特殊模式,但我认识到这很难实现(并且会消耗可能更好的资源)使用,如更符合一致)。无论如何,通过正确构建代码,可以避免ODR违规而无需付出极大的努力,因此我们作为程序员可以应对这种缺少链接器检查的问题。
但是,通过打开和关闭来改变代码功能的宏正在与ODR进行危险的调情,具体问题是_SECURE_SCL和_HAS_ITERATOR_DEBUGGING都是这样做的。乍一看,这似乎并不那么糟糕,因为您应该已经可以控制在构建系统中项目范围内定义的宏。但是,单独编译的库会使事情变得复杂 - 如果您使用_SECURE_SCL构建(例如)Boost,这是默认设置,则您的项目不能关闭_SECURE_SCL。如果您打算在项目中关闭_SECURE_SCL,那么现在必须相应地重新构建Boost。根据所讨论的单独编译的库,这可能很难(根据我的理解,使用Boost,它可以完成,我从来没有想过如何)。
他在评论中稍后列出了一些可能的解决方法,但没有一个看起来适合这种情况。其他人报告说通过在 boost / config / compiler / visualc.hpp 中插入一些定义来编译boost时能够关闭这些标志,但这对我来说是 NOT 。但是,在 tools / build / v2 / user-config.jam 中插入以下行 VERBATIM 就可以了。请注意,空格对于增加阻塞很重要。
using msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ;
答案 1 :(得分:2)
使用不同的堆实现进行编译时,通常会发生此类问题。在VS中,可以要求将CRT链接(作为静态库),或者保留为动态库。
如果您使用的库在其链接堆中分配内存,并且您的程序尝试使用另一个堆解除分配,则会遇到麻烦:要释放的对象不在已分配的对象列表中。
答案 2 :(得分:1)
我已经在我的系统上测试了你的代码,它运行正常。我认为您的编译器和构建Boost.Signals库的编译器之间存在不匹配。尝试下载Boost源代码,并使用与构建代码时相同的编译器编译Boost.Signals。
仅为我的信息,您使用的是什么编译器(和版本)?
答案 3 :(得分:1)
_HAS_ITERATOR_DEBUGGING
和_SECURE_SCL
。
为了解决这个问题,我手动构建了boost库。我不需要乱用配置文件。以下是我使用的两个命令行:
<强> 86 强>
bjam debug release link = static threading = multi runtime-link = shared 限定= _SECURE_SCL = 0 限定= _HAS_ITERATOR_DEBUGGING = 0 - 带信号阶段<强> 64 强>
bjam debug release link = static threading = multi runtime-link = shared 限定= _SECURE_SCL = 0 限定= _HAS_ITERATOR_DEBUGGING = 0 address-model = 64 - with-signals stage
这会构建以下文件:
libboost_signals-VC90-MT-1_43.lib
libboost_signals-vc90-mt-gd-1_43.lib
希望有所帮助。