Frequently Asked Questions about ZLIB.DLL This FAQ is about the design, the rationale, and the use of ZLIB.DLL. If you have general questions about zlib, you should check the file "FAQ" found in the zlib distribution, or at the location http://www.gzip.org/zlib/zlib_faq.html 1. Why am I having problems using ZLIB.DLL? My application works with the static build of zlib just fine, and I didn't make any modification when recompiling it for ZLIB.DLL. - Make sure you define ZLIB_DLL before including "zlib.h". Applications that link to ZLIB.DLL will work properly if the source files are compiled in this (or in a compatible) way, and the executables are linked to MSVCRT.DLL. 2. Why do I have to do this? When I use other libraries, I can link my code to their static or dynamic versions, without needing any source code modification or recompilation. - In order to preserve the backwards compatibility with the older versions of ZLIB.DLL, and give the ability to use zlib to the non-C programmers at the same time, we had to do this compromise. 3. What exactly is this mess about, and why is it happening? - It's about the calling convention used for the zlib functions. If linked in statically, zlib uses the C (CDECL) convention. If linked in dynamically (via ZLIB.DLL), it uses the STDCALL convention. The ZLIB_DLL macro switches on the use of STDCALL. It happens because we need to preserve compatibility with the old releases of ZLIB.DLL that use STDCALL, and, at the same time, we must provide support for programmers who use other programming languages with bindings that require CDECL. 4. Why not use the STDCALL convention all the time? It's the standard convention in Win32, and I need it in my Visual Basic project! - Most of the Win32 API functions (without varargs) use indeed the STDCALL (WINAPI) convention, but the standard C functions use the default CDECL. If one calls Win32 functions such as CreateFile(), sometimes it makes sense to decorate one's own functions with STDCALL. But if one is aiming at ANSI C or POSIX portability, and calls functions such as fopen(), it is not a sound decision to include or to use non-ANSI constructs only to make one's functions STDCALL-able. This is not the biggest problem, however. Technically, STDCALL is not bad; it is even a little faster than CDECL. The problem of using STDCALL is actually a problem of using any explicit calling convention. FASTCALL falls into the same category. Explicit specification of calling conventions, whether it's direct or indirect via a macro, happens commonly in Windows, but it is regarded as a noisy, non-standard C quirk on other platforms. It isn't possible to write an ANSI C -conforming program, for example, if it is necessary to specify calling conventions. Libraries can hide the dirty stuff in header files, under macros, but callbacks will still remain exposed. This is why the zlib callbacks will not be decorated. (The old Windows callbacks, such as WndProc, are decorated, but the newer ones are not.) There is one more problem with explicit, non-default calling conventions: the ability to use zlib in other programming languages. Some of them, like Ada (GNAT) and Fortran (GNU G77) have C bindings implemented initially on Unix, hence relying on the C calling convention. So we are decorating the functions using STDCALL in ZLIB.DLL to maintain compatibility with the old versions, but we are using the default CDECL in the static library, to allow other programming languages to use zlib in a portable fashion, via C bindings. 5. Why not use the default (CDECL) convention all the time? It's the standard convention in C, and I need it in my Ada project! - Originally, ZLIB.DLL was intended to run under Visual Basic, and VB6 and earlier need STDCALL. We admit that cluttering the main zlib sources, for the sake of interfacing with Visual Basic and at the expense of other programming languages, is not fair. It would have been better to maintain a "VB-only" project in the contrib/ directory, and to build a custom ZLIBVB.DLL, for example -- as we did with the Delphi projects. Another possible solution would have been to build STDCALL wrappers around the CDECL-exported functions. But this was the accident that we have to live with, in order to maintain binary compatibility with the older versions of ZLIB.DLL. 6. If my application uses ZLIB.DLL, do I have to link it to MSVCRT.DLL? Why? - The executables (.EXE, .DLL, etc.) that are involved in the same process and are using the C run-time library (i.e. they are calling any standard C function), must link to the same library. There are several libraries in the Win32 system: CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. Since ZLIB.DLL is linked to MSVCRT.DLL, the executables that depend on it must also link to MSVCRT.DLL. 7. Why are you saying that ZLIB.DLL and my application must be linked to the same C run-time library (CRT)? I linked my application and my DLLs to different C libraries (e.g. my application to a static library, and my DLLs to MSVCRT.DLL), and everything works fine. - If a library invokes only pure Win32 API (i.e. accessible via ), its DLL build will work in any context. But if a library invokes standard C functions, things get more complicated. There is a single Win32 library in a Win32 system. Every function in this library resides in a single DLL module, that is safe to call from anywhere. On the other hand, there are multiple versions of the C library that are all at the same time in the system, and all of them have internal states, therefore it is dangerous to intermix them with each other. Intermixing multiple C libraries is possible, as long as their internal states are kept intact. The Microsoft Knowledge Base article Q140584 "HOWTO: Link with the Correct C Run-Time (CRT) Library" enumerates some of the potential problems raised by intermixing, but does not offer a complete description of how to avoid them, except by advising not to mix the C libraries. If you can send us more information about this issue, we will highly appreciate it. (But please do NOT send us source code from Microsoft, even if it comes with your legitimate copy of Visual C++!) If this kind of intermixing works for you, it's because your application and DLLs are avoiding the corruption of the CRT's internal states, due to a fortunate accident. It's not because those libraries really work together. Also note that linking ZLIB.DLL to non-Microsoft C libraries (such as Borland's) raises similar problems. 8. Why are you linking ZLIB.DLL to MSVCRT.DLL? - MSVCRT.DLL exists on every Windows 95 with a new service pack installed, or with Microsoft Internet Explorer 4 or later, and on all other Windows 4.x or later (Windows 98, Windows NT 4, or later). It is freely distributable; if not present in the system, it can be downloaded from Microsoft or from other software provider for free. The fact that MSVCRT.DLL does not exist on a virgin Windows 95 is not so problematic. The number of Windows 95 installations is rapidly decreasing, Microsoft stopped supporting it a long time ago, and many recent applications from various vendors including Microsoft, do not even run on it. Even without these arguments, no serious user should run Windows 95 without a proper update installed. There is also the fact that the mainstream C compilers for Windows are Microsoft Visual C++ 6.0, and gcc/MinGW. Both are producing executables that link to MSVCRT.DLL by default, without offering other dynamic CRTs as alternatives easy to select by users. 9. Why are you not linking ZLIB.DLL to <> ? - We considered and abandoned the following alternatives: * Linking ZLIB.DLL to a static C library (LIBC.LIB, or LIBCMT.LIB) is not a good option. People are using ZLIB.DLL mainly to save disk space. If you are linking your program to a static C library, you may as well consider linking zlib in statically, too. * Linking ZLIB.DLL to CRTDLL.DLL looks very appealing, because CRTDLL.DLL is present on every Win32 installation. Unfortunately, it has a series of problems: it raises difficulties when linking to the Microsoft C++ libraries, it is not thread-safe, and Microsoft has discontinued its support a long time ago. * Linking ZLIB.DLL to MSVCRT70.DLL, supplied with the Microsoft .NET platform and Visual C++ 7.0, is not a good option. Although it can be downloaded and distributed freely, it is hardly present on today's Win32 installations. If it will become more popular than MSVCRT.DLL, and will be pre-installed on the future Win32 systems, we will probably think again about it. * Linking ZLIB.DLL to NTDLL.DLL is not possible. NTDLL.DLL exports only a part of the C library, and only on Windows NT systems. 10. I understand your reasons. However, my project needs ZLIB.DLL linked to something different than MSVCRT.DLL. What can I do? Feel free to rebuild this DLL from the zlib sources, and link it the way you want. It is required, however, to clearly state that your build is unofficial. Another thing that is not required, but highly recommended, is to name that custom DLL differently, and/or to install it in a private directory that can be accessed by your application, but is not visible to the others (e.g. it's not the SYSTEM or the SYSTEM32 directory, and it's not in the PATH). Otherwise, your build may clash with applications that link to the official build. For example, in Cygwin, zlib is linked to their runtime CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. 11. My I include additional pieces of code that I find useful, link them in ZLIB.DLL, and export them? No. A legitimate build of ZLIB.DLL must not include code that does not originate from the official zlib sources. But you can make your own private build, and give it a different name, as suggested in the previous answer. For example, in Borland Delphi and C++ Builder, zlib is part of the standard VCL library. If an application links to VCL dynamically, the name of the distributable binary (VCLxx.DLL) does not posess any danger of clashing with a legitimate but incompatible ZLIB.DLL. 12. I see that I may have all kinds of problems if I use ZLIB.DLL. Do you recommend to link zlib in statically? Do I get rid of problems? - Yes, definitely. In fact, unless you are distributing a large number of executables, each of them linking to zlib, you will save space by linking zlib in statically (assuming that you would otherwise distribute ZLIB.DLL with your application). zlib is not a big library, and the space saved by ZLIB.DLL is little. Much of the actual size of the DLL is due to the 4KB alignment in the binary. But you may have reasons, other than size, to use the DLL. That is entirely up to you.