我的应用(使用VS20 15 编译)加载第三方DLL(使用VS20 08 编译)。在发布中运行应用程序只需要从目标计算机上的MS网页获取VS2008和VS2015的可再发行组件。
在调试模式下运行应用程序(例如在另一台开发人员计算机上)需要VS2008的 debug 可再发行组件,这应该避免。复制第三方DLL旁边的msvcX90 d .dll不会导致成功。任何想法如何说服Windows加载VS2008调试运行时?我的应用程序是否需要清单以及它是哪一个?
关于混合运行时的FYI
是的,我对混合运行时不满意,但在我的上下文中,两个运行时都不会互相干扰。并且重新编译第三方DLL不是一种选择。
进一步简化问题。如何在VS2015编译的应用程序中加载msvcr90d.dll?
LoadLibrary(L"msvcr90d.dll");
答案 0 :(得分:2)
从评论中读取了很多资源后,我的方法是如何在VS2015(发布和调试)中加载VS2008(msvcr90d.dll)的调试可再发行组件。
首先,您的应用程序需要一个清单文件。什么是清单文件?这页很好地总结了它:http://www.samlogic.net/articles/manifest.htm
清单是一个XML文件,其中包含通知Windows的设置 如何在程序启动时处理程序。清单可以 嵌入在程序文件中(作为资源)或可以找到它 在一个单独的外部XML文件中。
清单文件可以放在我们的可执行文件旁边,也可以嵌入(默认)。要切换/更改它,请转到Projects Property Page -> Linker -> Manifest Tool -> Input and Output -> Embed Manifest
。
下面的源代码中的pragma为我们的(默认情况下)嵌入式清单文件添加了几行到我们的可执行文件中。
转到C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT
并复制可执行文件旁边的所有文件
打开新的Microsoft.VC90.DebugCRT.manifest
并移除令牌publicKeyToken="1fc8b3b9a1e18e3b"
。如果它在里面,Windows会一直拒绝加载msvcr90d.dll。请不要问我为什么。
编译并执行您的程序
#include <Windows.h>
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
"name='Microsoft.VC90.DebugCRT' "\
"version='9.0.21022.8' "\
"processorArchitecture='amd64' "\
"\"")
int main()
{
auto* lib = LoadLibrary(L"msvcr90d.dll");
if (!lib)
{
return -1;
}
FreeLibrary(lib);
return 0;
}
<强>背景强> 为什么我们有一个外部清单文件(Microsoft.VC90.DebugCRT.manifest),以及这个解决方案的嵌入式文件(通过编译指示)?看起来pragma只提供了有限的选项,你的清单看起来如何。一种选择是引用另一个包含更多信息的清单文件。
编辑:此MSDN enter link description here帖子中的答案也有很大帮助。
编辑2:您可以将此嵌入清单嵌入到您的可执行文件(也可以通过“属性页”),而不是从嵌入式清单引用到外部Microsoft.VC90.DebugCRT.manifest
,但是我得出这个结论为时已晚,但我的初步解决方案希望能提供更多见解
答案 1 :(得分:1)
我只是通过在清单中嵌入第三方DLL解决了类似的问题。
运行取决于我的第三方DLL,表明它正在C:\ Windows \ System32中寻找msvcr90.dll。显然,这不是正确的位置-应该在WinSxS文件夹之一中查找。
幸运的是,对于我的第三方DLL,我拥有源代码和原始的makefile,因此我能够生成正确的清单文件,并使用mt命令将其嵌入DLL中:
mt -manifest myDLL.dll.manifest -outputresource:myDLL.dll;2
之后,我能够正确加载DLL,而我的R6034错误消失了。