使用发布版EXE调试DLL

3

可以用发布模式的EXE执行调试模式的DLL吗?

我正在尝试这种情况,但是EXE不会加载调试DLL,并抛出错误“此应用程序无法启动...”。

我知道这不是一个好的方案,但由于某些要求,我必须使其工作。


是的,这是可能的。加载失败应该有它自己特定的原因,比如缺少依赖项。 - Roman R.
请检查您的调试构建设置。通常,当缺少库或者您使用了“多线程调试 DLL”选项进行代码生成时,会出现此错误。 - Abhineet
@Abhineet:我尝试使用“多线程 DLL”选项进行构建。问题仍然存在... - Nipun
不用担心,只需尝试“多线程”或“多线程调试”。 - Abhineet
2个回答

5

如果您的dll接口不依赖于在debug和release模式下可能看起来不同的类,它将可以正常工作。

例如,在MSVC中,std::string和std::vector在debug和release模式下不兼容(Fences...)

因此,举个例子:

std::string GetName();

这将无法工作。

此外,由于调试版和发布版使用不同的运行时库,因此不应移动newdelete。但是无论如何,您应该始终在与new相同的上下文(dll / exe)中使用delete


我创建了一个非常基本的DLL,它只是返回一个整数值。 - Nipun

3

是的,这可以解决问题。

你的“应用程序无法启动”问题很可能是因为你将调试版本的DLL(在Visual Studio上建立在自己的机器上)复制到了没有安装DEBUG CRT的机器上。通常,将MSVCRTD(版本).dll复制到与程序文件相同的目录中就可以解决这个问题。我之前回答过一些类似的问题,链接在这里

最好的办法是始终将所有二进制文件链接到同一个动态的MSVCRT DLL,这样它们都共享相同的运行时。

另一个简单的解决方法是将DEBUG DLL编译为使用相同版本的MSVCRT DLL(或静态链接到CRT)。在VS项目属性页面的某个地方(我想是代码生成),有一个下拉菜单用于选择CRT。将零售版MSVCRT链接到调试DLL中或者静态链接也没问题。

需要注意的问题是当不同的二进制文件链接到不同的调试C运行时库时。如果EXE链接了发布版本的MSVCRT dll,但DLL链接了调试MSCVRTD DLL,在某些情况下会导致问题。这是因为句柄和内存块由两个不同的CRT实例跟踪。

例如:

  1. 如果你在EXE中分配内存,但在DLL中释放内存。反之亦然。

  2. 使用fopen()在EXE中打开文件句柄,但在EXE中使用或关闭它(反之亦然)。

  3. 对于任何DLL接口的头文件,在头文件中实现任何形式的内联函数或方法是导致#1或#2发生的简单方法。

  4. 共享STL对象(std::string、std::list、std::vector)对于混合CRT使用来说绝对不行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接