tags:

views:

2007

answers:

5

I am trying to recreate an existing C Win32 DLL with a single, simple function. I have managed to do this using VS C++ 2008 Express, and my new DLL works on my Vista dev machine, and on the client's XP machine. However, it doesn't work on other sites. I have checked dependencies and my DLL requires MSVCR90D.dll and KERNEL32.dll, where the original DLL only requires KERNEL32.dll.

What is MSVCR90D.dll, and how do I create a simple Win32 DLL without this dependency?

+6  A: 

The D at the end of MSVCR90D.dll shows that you compiled your .exe in debug mode. You should only distribute your application in release mode.

You can make sure they have everything they need by having them install the Microsoft Visual C++ 2008 Redistributable Package x86 or x64. Otherwise you can probably simply copy the files they need for them by finding them on your computer (check first at %systemroot%\system32)

Please see this MSDN link.

Brian R. Bondy
I can't give +1 to an answer that recommends scraping the runtime DLLs out of your computer's system32 folder. Not a good idea. The problem is that the side-by-side assembly mechanism needs to be handled correctly on the target machine, and a simple file copy is not likely to be correct.
RBerteig
@RBeteig: What do you mean by: "side-by-side assembly mechanism"? What is the problem with putting the dlls in the folder you need for your app? I don't recommend copying to their system32 folder.
Brian R. Bondy
A: 

Check if your client's machine has the 2008 runtime installed on his system or not. If not you can either get it installed on his/her system or statically compile the runtime with your application.

dirkgently
+3  A: 

Link with the static version of the C runtime library. The setting is under "Code generation" in the project properties. Then you won't need to worry about the MSVCR* DLLs at all.

RichieHindle
You always need to worry if you are writing a plugin for an application so that you don't end up with incompatible implementation of malloc/free for example. In any case, the D meant Debug, and there are lots of reasons to never deploy a Debug build.
RBerteig
@RBerteig: In general you're right about malloc/free etc., but in this case ProfK is recreating an existing DLL that doesn't have a dependency on the CRT DLL. He's not going to introduce problems by making his new DLL work the same way.
RichieHindle
Sorry, on a rereading it looks like I may have come off a bit harsh there. I have frequently seen the advice given to just link static when the real problem is the Debug build, and it is a pet peeve of mine these days. It can actually do harm when the hosting application requires that the dependency really be on the very same runtime. If we assume that the old DLL really did work as built, then static linkage may indeed be the right answer.
RBerteig
+2  A: 

The 'D' in the name means debug. This is a clear indicator of Visual Studio's Debug build. Use the Release build, and all will be well.

If the target system doesn't have the C runtime yet, you should generally use the official installer to put it there. Some of the versions of the runtime you might want to know about are these:

You can also develop a complete installation package that includes the redistributable DLLs (but never a debug DLL) needed by your application and handles the installation of side by side (SxS) assemblies into the system assembly cache correctly, using a technique known as merge modules. This approach is easier if you have the full installation of Visual Studio (not the free VS Express edition) but the resulting installation packages still may not handle installation of the runtime on older (such as Win 2K or 9x) platforms well at all.

The MSDN article Redistributing Visual C++ Files describes what the rules are, and how to comply with them as easily as possible. It provides a starting point to learn more about many issues related to deployment.

If the original DLL whose functionality you are replacing did not have a reference to MSVCR90.DLL, then it must have been statically linked to the runtime. You probably should check on the assumptions of the intended application that will be calling your DLL. Mixing C runtime libraries in a single process is not always easy. If the hosting application is already using MSVCR90.DLL, then you really should too. This is a larger issue than fits in an answer to the specific question at hand, however, so I'd encourage you to research it and ask new questions as needed.

Another approach to avoiding the installation of the later runtime DLLs is to link to MSVCRT.DLL, which is distributed with modern versions of windows as a system component. This is the runtime that was shipped with Visual C 6.0, lightly updated for critical issues and kept current to match the OS. It isn't available for 64-bit builds at all, and it is quite difficult to trick Visual Studio into using it in place of the newer runtime.

RBerteig
A: 

Likely what you want to do is build a Release version of your DLL, test it, and distribute that instead of the Debug build that you're distributing now.

However, it is possible to make a Debug DLL that depends on MSVCR90.DLL, the non-debug version of that DLL. To do this (VS 2008 SP1, instructions are similar for other VS):

  1. Go to Project Properties (right-click on the project in the Solution Explorer pane, pick Properties from the menu).
  2. Go into Configuration Properties\C/C++\Code Generation.
  3. Under Runtime Library, you probably have "Multi-threaded Debug DLL" selected. Change this to "Multi-threaded DLL".

You'll have to recompile everything, but you should now be linking against the non-debug VS DLLs.

gdunbar