是否可以使用发布模式EXE执行调试模式DLL?
我正在尝试这种情况,但EXE不加载调试DLL并抛出错误“此应用程序无法启动...” .
我知道这不是好事,但由于某些要求,我必须做到这一点 .
是的,这可以工作 .
您的"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使用是一个明确的禁忌 .
如果您的dll接口对调试和发布中可能看起来不同的类没有依赖关系,它可以工作 . 例如MSVC中的std :: string和std :: vector在调试和发布中不兼容 . (栅栏......)
所以举个例子
std::string GetName();
不管用 .
另外new和delete不应该被移位,因为调试/发布使用不同的运行时 . 但无论如何你应该始终 delete 在相同的上下文(dll / exe)中 new .
delete
new
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使用是一个明确的禁忌 .
如果您的dll接口对调试和发布中可能看起来不同的类没有依赖关系,它可以工作 . 例如MSVC中的std :: string和std :: vector在调试和发布中不兼容 . (栅栏......)
所以举个例子
不管用 .
另外new和delete不应该被移位,因为调试/发布使用不同的运行时 . 但无论如何你应该始终
delete
在相同的上下文(dll / exe)中new
.