c++ - 使用 Visual Studio 将静态构建的库链接到共享库的潜在内存风险

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

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

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

最佳答案

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

  • 全局初始化:在 DLL 中,它们都运行。在静态库中,链接器只有在满足一些 Unresolved external 条件时才会引入目标文件,因此依赖组件使用全局对象的构造函数或初始化表达式进行 self 注册的系统会失败。

  • 共享 CRT:在静态库中,所有对标准库的调用都在链接时解析,主应用程序和库函数都调用标准库的同一个拷贝。在 DLL 中,您冒着拥有两个标准库拷贝的风险,如果您注意不要共享任何标准库对象(如 FILE*std::string,甚至 malloc/free 对)在库和应用程序之间。

第二件事很可能是什么在咬你。有一种懒惰的修复方法:使用标准库 DLL,还有一种更好的修复方法:计算内存和对象生命周期,不要尝试在一侧分配而在另一侧释放,或者共享 C++ 类布局边界。虚拟函数可以跨边界正常工作。

“更好”方法的优点是插件可以在任何版本的编译器中构建,这对于开发周期后期的维护来说是一件大事。

关于c++ - 使用 Visual Studio 将静态构建的库链接到共享库的潜在内存风险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9446059/

相关文章:

c++ - 战舰游戏 - 跟踪船只

visual-studio - Visual Studio - "restore"信息栏中的代码重构错误

c# - TD 不能嵌套在 TABLE 中

c - 可疑的静态链接可执行文件大小

c++ - 简单 Qt C++ 应用程序中的链接器错误

c++ - 'const' 限定符何时保证变量是常量表达式?

C++ 静态类成员 - 语法错误

c++ - 为什么要更改 C++ 中特定警告的警告级别?

c++ - MSBuild 在 native 依赖 dll 的内部更改后重新链接每个 native 项目

Java/JNI/MSVC java.lang.UnsatisfiedLinkError 到我的 DLL 函数