使用Visual Studio将静态构建的库链接到共享库可能存在内存风险

时间:2012-02-25 17:00:11

标签: c++ visual-studio linker boost-asio firebreath

我正在研究一个在Windows上崩溃的跨平台Firebreath插件。我使用一个静态库,其中包含引用boost.asio的类。当我将这个库与插件dll链接时,我观察到与io_service子系统交互时的崩溃(即,在套接字构造期间)。当我将静态库与普通可执行文件链接时,问题确实。当我将静态库的内容直接编译到plugin dll项目中时,崩溃会发生 not 。我已经竭尽全力确保Windows上构建环境的所有方面都是一致的(构建模式,Visual Studio版本等)。另外,我已经对boost.asio标题进行了防火墙处理,因此插件dll代码没有boost.asio子系统的可见性(不幸的是,vs2008和vs2010没有效果)。据我所知,我已尽一切可能确保构建环境表现良好但问题仍然存在。

社群能否就可能暴露或解决问题的潜在风险或方法提出任何建议?

2 个答案:

答案 0 :(得分:1)

链接静态库与加载DLL之间有两点显着不同:

  • 全局初始化:在DLL中,它们都运行。在静态库中,如果链接器满足某些未解析的外部,则链接器只会引入一个目标文件,因此依赖于使用构造函数注册自身的组件或全局对象的intiialization表达式的系统会失败。

  • 共享CRT:在静态库中,所有对标准库的调用都在链接时解析,主应用程序和库函数都调用标准库的同一副本。在DLL中,您可能会有两个标准库副本,如果您小心不要共享任何标准库对象(例如FILE*std::string甚至{{1}库和应用程序之间的/ malloc对。

第二件事很可能是什么在咬你。有一种懒惰的方法来解决它:使用标准库DLL,以及一种更好的修复方法:找出内存和对象的生命周期,不要尝试在一方分配,另一方免费,或者共享C ++类布局边界。虚函数在边界上工作正常。

“更好”方式的优点是可以在任何版本的编译器中构建插件,这对于以后在开发周期中的维护而言将变得非常重要。

答案 1 :(得分:0)

在FireBreath插件准备脚本中,尝试turning on the WITH_DYNAMIC_MSVC_RUNTIME flag