Wednesday, 5 October 2011

The art of avoiding the Microsoft Visual C Run-Time

When it comes to writing C/C++ code which will run on any version of Windows - down to 2000 or even 9x, NOT linking to the Microsoft Visual C Run-Time library (MSVCRT) is often a very good or even necessary thing to do. Doing so means you do not need to install MSVCRT with your application and it will also reduce the file size of your application/DLL by not linking with it. If the required CRT is missing when your application is run, expect a rather unfriendly dependency error for your customers and, as for DLLs, expect a crash.

Does lack of CRT make life for the coder harder? The problem with not using any C Run-Time library is that you lose a lot of CRT functions and some features of C++ (such as the new and delete operators which use malloc/free). I have been writing C/C++ code without using CRT now for many years and quite honestly, once you get used to it, it really isn't too difficult. There is an art (if you like) to finding API's, finding alternative functions or writing your own functions, and I actually find this makes coding in C more enjoyable (albeit more tedious perhaps). When it comes to the new and delete operators, you can just use HeapAlloc and HeapFree (or LocalAlloc/LocalFree/GlobalAlloc/GlobalFree which are now just wrappers for HeapAlloc/HeapFree). Note that ZeroMemory is just a macro for memcpy, and so you will have to write your own. For strcpy, strcmp or strcat there's the lstrcpy, lstrcmp and lstrcat, and you can use the wsprintf API for formatting strings.  Microsoft do prefer that you avoid using these functions however, as they do not have a buffer length argument. As long as you are careful though (as all C coders should be), then this will not be an issue. The string-to-integer functions; atoi or atou; will need your own implementations, but there are many out there you can use. For example, NSIS provides myatoi and myatou in its API specially for you to use if you are writing an NSIS plug-in. You may grab those implementations from the NSIS source code too if you wish.

To disable linking to CRT, you need to Ignore default libraries in Visual Studio. As of VS2008, you must also disable the XML manifest (under Linker). The XML manifest contains an entry that will tell Windows your binary depends on MSVCRT, even if you haven't linked against it. This, for executables, allows Windows to avoid executing it rather than it just crashing later on.

If you still cannot build, you may find disabling buffer security checks and disabling any optimisations (under C/C++). I have found that a typical DLL can be 56KB with CRT and only 5KB without.


No comments:

Post a Comment