7
votes

I've created a DLL project in VS 2005 for native Win32/unmanaged C++, call it myProj.dll. It depends on a 3rd-party commercial DLL that in turn depends on msvcr90.dll (I assume it was built from a VS 2008 project). I'll call it thirdParty.dll.

My DLL project builds just fine in VS2005. I've built a test app (again, VS 2005 Win32 C++) that links to myProj.lib. (As an aside, judging by the small size of the .lib, and by the fact that, at run-time, the app must locate myProj.dll, I'm guessing that the .lib is just a wrapper for a call to loadLibrary() that loads the actual DLL; is that close?)

My problem is that, at run-time, the test app cannot locate msvcr90.dll (nor msvcp90.dll), the dependency on which stems from the thirdParty.dll.

I've installed Microsoft's redist package, and so have all the std (9.0) C++ libraries in c:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_... . What's more, if I point the dependency walker at thirdParty.dll, it happily resolves the references to that location.

But, if I point depends.exe at my test app (.exe) or myProj.dll, msvcr90.dll and msvcp90.dll are not found.

I'm guessing there's something I need to configure in VS2005 so that the .exe or myProj.dll are aware of the location of the 9.0 versions of the std C++ libraries (presumably where the redist package installed them in C:\WINDOWS\WinSxS), but I can't seem to figure out what it is. Am I on the right track?

I note that, if I simply copy the msvc*90.dll files to my app directory, then the dependency is resolved, but I get the run-time error about improper loading of std c++ DLLs, etc.

Thanks immensely in advance.

4

4 Answers

6
votes

This looks like a "Side-by-Side Assemblies" issue to me.

From what I can tell, Microsoft in an attempt to stop the DLL Hell problems of past years has introduced a concept of "Side-by-Side Assemblies".

In a nut shell it means that your application needs to tell Windows which version of the CRT it was designed to work with. When the application is installed Windows will make sure you application gets its own private copy of these DLL files.

To make it all work you need to embed the application's DLL dependencies into the applications Manifest file and attaching it to the project using the Manifest Tool, Input and Output section of the application project settings.

As an example here is the manifest I use for the Zeus for Windows IDE:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
      name="Xidicone.Windows.Zeus for Windows"
      version="3.9.6.69"
      processorArchitecture="X86"
      type="win32" />

  <description>Zeus for Windows</description>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
            type="win32"
            name="Microsoft.VC80.CRT"
            version="8.0.50608.0"
            processorArchitecture="x86"
            publicKeyToken="1fc8b3b9a1e18e3b" />
    </dependentAssembly>
  </dependency>

  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="X86"
          publicKeyToken="6595b64144ccf1df"
          language="*" />
    </dependentAssembly>
  </dependency>
</assembly>

Finally, if you plan to make an installer you will need to add the same versions of these DLL files to the application installer or alternatively have your installer run the Microsoft CRT redistributable installer.

FWIW I only found out about this when a user reported that Zeus no longer ran on Windows XP because of a missing MSVCRT runtime DLL file, yet Zeus had been working fine for over 10 years without ever once having to ship with a MSVCRT runtime DLL file.

2
votes

Did you install the SP1 version of the msvc 2008 redist?

It is not a problem if depends.exe cannot find the msvcr90.dll, if you use the microsoft installer it is automatically installed in the correct location, and will be found if your application is run. It does not help if you copy the dll's to your application directory if you do not create a manifest.

But can you tell the exact error message you get?

You can also take a look here and here regarding the manifest.

1
votes

I would ask the third party dll people about this.

1
votes

I have the same problem some days ago. myProj.dll depends on a thirdParty.dll, which uses msvcr90. If I build a test.exe using directly myProj.dll, it is ok. But if I use loadLibrary(myProj.dll) in test.exe, the call will just fail. The same would happen if I try loadLibrary(myProj.dll) in a Java program.

After some investigation and research on Internet, the following steps have resolved my problem.

  1. Make sure that NO msvcr90 is on the PATH. You can use process explorer (procexp.exe of SystemInternals) to find out all msvcr90 currently loaded in your environment. As a matter of fact, starting from VC 2005, C runtime libraries should only be installed in the Global Assembly Cache (\winsxs....), not even under windows, or windows\system32.

  2. embed the dll manifest in myProj.dll. After cl.exe and link.exe producing myProj.dll, a corresponding manifest is also produced. Then use mt.exe -inputresource myProj.dll.manifest -out myProj.dll;2

The above solves my problem, hope that it could be of any help to you. BTW, I am using VC 2008 under Windows 2008 R