2

我有一个 DLL 和 3 个使用这个 DLL 的应用程序。(这些应用程序不会同时运行)

在 3 个应用程序中,2 个运行良好,但 1 个应用程序在一段时间后没有从一个 DLL 函数获得响应(具体而言,在第 7 个函数调用时)。此外,如果我使用调试版本的应用程序或我的 DLL,则代码可以正常工作。它仅在发布版本中停止。

在度过了 2 个不眠之夜之后,我发现如果我将 DLL 的项目属性从/MDto 更改为 to /MT,这个应用程序可以正常工作。

我不知道为什么会发生这种情况。为了睡眠不足的程序员,谁能解释一下!

更新:

我将在市场上发布这个 DLL,我不能说是否会构建用户应用程序/MT/MTD其他什么......有什么方法可以确保它可以与任何应用程序一起使用。

4

2 回答 2

2

在 Windows 中,EXE 和 DLL 文件是模块。每个动态编译的模块 (/MD) 共享一个堆。因此,在动态模块中,如果一个模块调用 malloc(或 new)而另一个模块对对象执行 free(或 delete),那么一切都很好。

在 C 运行时中编译为链接的每个模块都静态地获得自己的堆。 如果一个静态模块分配一个对象,而另一个静态或动态模块试图释放该对象,程序将崩溃,因为分配和释放是针对不同的堆。

跨模块边界分配和释放内存

于 2013-09-05T12:51:28.603 回答
0

/MD 将运行时链接为动态的,如果您的计算机正确安装了运行时,则编译为 /MT 将起作用,因为运行时将包含在二进制文件中。

这也可以解释当您将其编译为调试模式时它可以工作,在调试模式下,运行时的调试版本静态链接到二进制文件中。

在这里查看有关该主题的一些讨论。

更新 另一个问题可能是使用不同选项编译 dll 的模块,如这篇msdn 文章中所述:

传递给链接器的给定调用的所有模块都必须使用相同的运行时库编译器选项(/MD、/MT、/LD)进行编译。

于 2013-09-05T11:58:19.707 回答