[Zlib-devel] RE: [png-implement] Binary-incompatible change in the DLL interface of zlib
Cosmin Truta
cosmin at cs.toronto.edu
Mon Jul 28 17:31:02 EDT 2003
On Mon, 28 Jul 2003, John Bowler wrote:
> The calling convention is frozen in when the library itself, or the
> DLL, is built. Therefore the header file distributed with the built
> library or built DLL (well, the stub .lib for the DLL) should say
> exactly what that calling convention was.
Ideally, yes.
Practically: NOT in the old interface, YES in the new one.
That's because the same header is used for the static lib and for the
DLL. When using the DLL, the macro ZLIB_DLL was turned on, and this one
used to switch WINAPI on, to be used with the DLL.
This policy was bad, bad, bad.
When the user forgot to turn ZLIB_DLL on, that user had a problem.
To add insult to the injury, the official makefile (that is, the file
"nt/Makefile.nt") was building the DLL without ZLIB_DLL turned on.
The result? Some builds of ZLIB.DLL had ZLIB_DLL turned on, some others
didn't. If you happened to have the wrong ZLIB.DLL in your system, the
app crashed. Most notably, the libpng-, libmng- and Mozilla-distributed
ZLIB.DLL use STDCALL, while GnuWin32 use CDECL.
Another bad side effect happened when you had a ZLIB.DLL, and you wanted
to build your app depending on it, but you didn't know whether you could
include "zlib.h" as-is, or to predefine ZLIB_DLL first.
> It doesn't make sense for someone building against an *already built*
> zlib to be able to change the meaning of the function definitions
> within the header file by changing the macros on the compiler command
> line or in the *calling* source code.
You are right. But this is what was happening in zlib, and this is what
*had* to be fixed.
> The actual function definitions within zlib.h should include
> __stdcall, __cdecl or __fastcall as appropriate. Then it doesn't
> matter what options are used either in the original zlib build (static
> library or DLL) or the calling app/lib build - the public zlib
> functions will always have the same calling convention.
Also true.
> The main problem seems to be that ZLIB_DLL causes a big switch to flip
> within the zconf.h header file on Windows (only) between WINAPI/WINAPIV
> (macros which define, in addition to other things, the calling convention)
> and *nothing* (no specification of calling convention.)
Correct. We had to get rid of this.
> But I don't see that changing the *static* library from implicit
> __cdecl to explicit __stdcall would break anything. The explicit
> definition will ensure that calling code is correct when recompiled.
It wouldn't break anything in C or C++, but it will cause problems in
other programming languages that interface with zlib via C bindings.
See question 5 in the DLL_FAQ:
http://www.cs.toronto.edu/~cosmin/pngtech/zlib/DLL_FAQ.txt
I will answer to Gerard right away, perhaps that will clarify the
problem of foreign languages.
The bottom line is, as you say, we have to use the same header file
without changes all the way (incl. the same calling convention), and
that has to be the default one: CDECL.
Cosmin
More information about the Zlib-devel
mailing list