首页 文章

使用发行版EXE调试DLL

提问于
浏览
3

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

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

我知道这不是好事,但由于某些要求,我必须做到这一点 .

2 回答

  • 2

    是的,这可以工作 .

    您的"application has failed to start"问题很可能是您将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实例跟踪 .

    例子:

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

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

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

    • 共享STL对象(std :: string,std :: list,std :: vector)对于混合CRT使用是一个明确的禁忌 .

  • 3

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

    所以举个例子

    std::string GetName();
    

    不管用 .

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

相关问题