使用发行版EXE调试DLL

时间:2013-02-28 10:21:10

标签: c++ debugging release

是否可以使用发布模式EXE执行调试模式DLL?

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

我知道这不是一个好的方案,但由于某些要求,我必须做到这一点。

2 个答案:

答案 0 :(得分:3)

如果您的dll接口对调试和发布中可能看起来不同的类没有依赖关系,它可以工作。 例如MSVC中的std :: string和std :: vector在调试和发布中不兼容。 (围栏......)

所以例如

std::string GetName();

无效。

另外new和delete不应该被移位,因为debug / release使用不同的运行时。但无论如何,你应始终delete在与new相同的上下文(dll / exe)中。

答案 1 :(得分:2)

是的,这可行。

您的“应用程序无法启动”问题很可能是您将DLL的调试版本(使用Visual Studio在您的计算机上构建)复制到未安装DEBUG CRT的计算机上。通常将MSVCRTD(版本).dll复制到与程序文件相同的目录中可以解决此问题。我之前的答案涵盖了其中一些here

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

另一个简单的解决方法是编译您的DEBUG DLL以使用相同风格的MSVCRT DLL(或静态链接到CRT)。 VS项目中的某个地方(我认为代码生成)是选择CRT的下拉列表。将零售MSVCRT链接到调试DLL或静态链接没有任何问题。

需要注意的是,当您将不同类型的调试C运行时链接到不同的二进制文件时。如果你有发布的MSVCRT dll为EXE链接,但是为DLL调试MSCVRTD DLL,那可能会在一些情况下引起问题。这是因为句柄和内存块由两个不同的CRT实例跟踪。

示例:

  1. 如果在EXE中分配内存,但在DLL中自由进入。反之亦然。

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

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

  4. 分享STL对象(std :: string,std :: list,std :: vector)对于混合CRT使用是明确的禁忌。