tags:

views:

622

answers:

7

Using Visual Studio 2008 and its C/C++ compiler, how do I create a Win32 DLL that is dependent only on other Windows DLLs, and has no dependency on the Microsoft C runtime?

I have some C code I want to place in a DLL that is entirely computation, and makes almost no use of C library functions.

For those it does use (eg memcpy), I'm happy to rework the code to use the Win32 API equivalents (eg CopyMemory).

A: 

Some Windows libraries depend on the C runtime (ODBC32.DLL, for example) so I think you are on a hiding to nothing here. Why would you want to do this, anyway?

anon
I think its fair to assume that any dependencies of the windows dlls will come with windows. I don't see your point.
John McAleely
If your code depends on a DLL like ODBC32 then it indirectly depends on the CRT, which comes with Windows - are you under the mistaken impression it must be distributed separately? And if you downvoted this answer, I have to ask - why?
anon
If I build my code with the microsoft C compiler, I must use the C runtime supplied with it, if I want the behaviour they document/suport. That requires distribution of said runtime with my code.I suppose I could 'discover' another C runtime knocking about in Windows and somehow dynamically link to it, but that's rather more work than I had in mind, especially when I don't actually need any of its functions...
John McAleely
You do not need to distribute the C runtime with your application, and you do not need to "discover" another C runtimne - you just use the one that all the other Windows applications use. I have a FOSS project that is a single Windows executable, no runtime distributed with it of any sort.
anon
right. But which version? VC adds a particular version of msvcrt to the manifest of the dll it produces. If windows can't find *that exact version* it won't load the dll. Are you shipping without manifests? Or do you lower the required version in the manifest?
John McAleely
To follow up after reading: http://stackoverflow.com/questions/135296/is-msvcrt-under-windows-like-glibc-libc-under-nix The response from the person claiming to be from MS makes things clear. If I want to use the C/C++ language in VC 2008, I need to redist that msvcrt. If I dont want to do that, I can either do as you propose, and get some sort of wierd interworking of vc2008's language assumptions and some old msvcrt, or I can remove the ambiguity by not linking at all to msvcrt (which the compiler clearly supports). I could well imagine that linking to the old one will 'mostly work'.
John McAleely
A: 

Compile it with static microsoft lib.

CiNN
As discussed here: http://msdn.microsoft.com/en-us/library/abx4dbyh(VS.80).aspxA modern microsoft C runtime is best not statically linked to a dll in a system where other libraries may be using the C runtime.
John McAleely
+4  A: 

Use the /NODEFAULTLIB linker option and (of course) make sure you have no actual dependencies on the runtime. You'll also have to specify & define your own entry point for the DLL using the /ENTRY linker option or alternatively have your own entry point function that matches the name exected by the compiler/linker (I forget what that is).

Matt Pietrek's article from way back when on LIBCTINY will probably have all the information you need:

Michael Burr
To quote from that article "Luckily, we've moved past those days, and in most cases you can rely on MSVCRT.DLL being available on your target machines." And Pietrek suggests that you should so depend.
anon
And is this *still true*? Lots has changed since the days of Windows 2000. I think now it is not the case that we should depend on MSVCRT on the machine. At least it is more complicated than Matt's statement indicates.
Cheeso
A: 

You'd have to make sure none of the Win32 DLLs you use need the C runtime as well or else you back at square one. Compiling your DLL statically won't matter if one of the Win32 DLLs depends on the C runtime.

The only way I can see this working is to statically link ALL your dependent DLLs (if that is even feasible) into your DLL. This of course means you would have to recompile to take advantage of any DLL updates.

Kelly French
+3  A: 

You may have more dependencies on the CRT than you think. It tears down resources like thread local storage, and global class initializers are run by the CRT before main().

Consider linking with a static CRT, as someone said, and if you really really don't want to, use /NODEFAULTLIB and /ENTRY as someone else said.

Oh, and instead of reworking memcpy, consider using the super-fast compiler intrinsic for it. You can turn on intrinsics with /Oi.

Drew Hoskins
I'm using memcpy as an example only.
John McAleely
As am I. There are many compiler intrinsics.
Drew Hoskins
Its a good idea, but do they document that the compiler's intrinsics don't depend on the existence of their own C runtime?I assume I could examine the compiler output to be sure, but that's more work than I had in mind...
John McAleely
intrinsics are all assembly hand-generated by the compiler. However, upon rereading the documentation, it isn't guaranteeing that the compiler will use the intrinsics if you tell it to. For example, perhaps it might use the intrinsic only for strcpy under or over a certain size, due to the different performance characteristics.
Drew Hoskins
A: 

The /NODEFAULTLIB linker flag is not actually the proper flag. It will ignore all default libs, including others like uuid.lib.

What you want is the /Zl compiler option, "omit default library name in .OBJ".

Koro
+2  A: 

for "Debug" mode try this:

  1. Go to Project\[Projectname] Properties...
  2. Open Configuration Properties
  3. Open C/C++
  4. Open Code Generation
  5. For Runtime Library Select Multi-threaded Debug (/MTd) instead of Multi-threaded Debug DLL (/MDd)

for "Release" mode, do same steps except that selecting Multi-threaded (/MT) in the last step.

This cause any C Runtime function that used in your program merged to your binary file.

Isaac