更改运行时库选项对运行时链接的影响

Posted

技术标签:

【中文标题】更改运行时库选项对运行时链接的影响【英文标题】:Effect of Changing Runtime Library Option on Runtime Linkage 【发布时间】:2016-08-21 21:08:40 【问题描述】:

Microsoft Visual Studio 2015 (v14.0) 我有一个包含 3 个项目的解决方案。

其中两个项目是 DLL,另一个是可执行文件。 可执行文件在运行时加载 DLL 并调用它们的函数并交换参数;使用 Window 的 LoadLibraryGetProcAddress API。

Release 模式下,当我将我的项目的Runtime Library 设置为Multi-threaded DLL 时,一切正常。这是Multi-threaded Debug DLL 用于Debug 模式。

如果我将Release 更改为Multi-threaded 或将Debug 更改为Multi-threaded Debug,我开始收到调试断言错误或内存访问冲突错误和其他类型的错误。 (当我更改它时,我会为解决方案中的所有项目更改它。)

我需要使用Multi-threaded 选项,这样可执行文件就不需要目标机器上的C++ 运行时库。我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

这是因为使用/MT 将实体的运行时(即 DLL 和可执行文件)分开,每个实体都有自己的运行时,因此有自己的堆,试图在一个中分配内存并在另一个中释放它最终会出错.因为其他模块不知道分配的内存。 另一方面,/MD 所有模块共享相同的运行时,并且运行时知道其中一个分配的内存,它将能够在另一个中释放它。因为一个运行时实例管理着整​​个内存。

编辑: 感谢 dxiv 评论。

【讨论】:

您所写的内容存在一些误解。地址空间是每个进程的,DLL总是与加载它们的进程以及由同一进程加载的其他 DLL 共享相同的地址空间。从同一进程中的任何其他位置访问在一个 DLL 函数中分配的内存是完全安全的。 not/MT 一起工作的是在一个DLL 的代码中分配内存(new),然后在另一个DLL 的代码中释放它(delete),因为/MT 每个DLL有自己的静态链接 CRT 副本。参见例如this answer。 @dxiv 你说得对,谢谢你的评论。我修改了答案。

以上是关于更改运行时库选项对运行时链接的影响的主要内容,如果未能解决你的问题,请参考以下文章

错误 MSB8024:不支持使用静态版本的 C++ 运行时库

运行时库只是一些动态链接的库文件吗? [关闭]

夏令时规则更改是不是使 C 运行时库无效?

Visual Studio 2015:在没有运行时库的情况下编译 C/C++

链接脚本在编程中的高级运用之二——运行时库和C++特性支持

一文带你弄懂Visual Studio:运行时库及MT/MTDMD/MDD