Reputation: 1863
My app (compiled with VS2015) loads a 3rd party DLL(compiled with VS2008). Running the app in release requires only the redistributables for VS2008 and VS2015 from the MS webpage on the target machine.
Running the app in debug mode (e.g. on another developer machine) requires the debug redistributables of VS2008, which should be avoided. Copying the msvcX90d.dll next to the 3rd party DLL does not lead to success. Any ideas how I can convince Windows to load the VS2008 debug runtime? Does my application need a manifest and which one is it?
FYI about mixing runtimes
Yes, I am not happy with mixed runtimes but in my context both runtimes will not intefer with each other. And recompiling the 3rd party DLL is not an option.
To simplify the problem even more. How can I load msvcr90d.dll in a VS2015 compiled application?
LoadLibrary(L"msvcr90d.dll");
Upvotes: 4
Views: 389
Reputation: 300
I just solved a similar problem by embedding my 3rd-party DLL with a manifest.
Running depends on my 3rd-party DLL showed that it was looking for msvcr90.dll in C:\Windows\System32. Obviously, that's not the correct location - it should be looking in one of the WinSxS folders.
Luckily, for my 3rd party DLL, I had the source code and original makefiles, so I was able to generate the correct manifest file and embed it in the DLL using the mt command:
mt -manifest myDLL.dll.manifest -outputresource:myDLL.dll;2
After that, I was able to load the DLL correctly and my R6034 error went away.
Upvotes: 1
Reputation: 1863
After reading the helfpful resources from the comments, here is my approach how to load the debug redistributable of VS2008 (msvcr90d.dll) in VS2015 (release and debug).
First your application needs a manifest file. What is a manifest file? This page summarizes it pretty well: http://www.samlogic.net/articles/manifest.htm
A manifest is a XML file that contains settings that informs Windows how to handle a program when it is started. The manifest can be embedded inside the program file (as a resource) or it can be located in a separate external XML file.
A manifest file can be placed next to our executable OR is embedded (default). To switch/change it go to Projects Property Page -> Linker -> Manifest Tool -> Input and Output -> Embed Manifest
.
The pragma in the source below adds a few lines to our (by default) embedded manifest file into our executable.
Go to C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\redist\Debug_NonRedist\amd64\Microsoft.VC90.DebugCRT
and copy all files next to your executable
Open the new Microsoft.VC90.DebugCRT.manifest
and remove the token publicKeyToken="1fc8b3b9a1e18e3b"
. If it is inside, Windows keeps rejecting to load the msvcr90d.dll. Please don't ask me why.
Compile and Execute your program
#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;
}
Background Why do we have an external manifest file (Microsoft.VC90.DebugCRT.manifest), and an embedded one (through the pragma) for this solution? It looks like the pragma only offers a limited amount of options how your manifest can look like. One option is to reference to another manifest file which contains more information.
Edit: The answers in this MSDN enter link description here thread also helped a lot.
Edit 2: Instead of referencing from the embedded manifest to the external Microsoft.VC90.DebugCRT.manifest
, you could already embed this one to your executable (can also be done by the Property Pages), but I came to this conclusion just too late but my initial solution hopefully gives some more insights
Upvotes: 2