[Zlib-devel] RE: [png-implement] Binary-incompatible change in the DLL interface of zlib
Cosmin Truta
cosmin at cs.toronto.edu
Thu Jul 31 00:30:02 EDT 2003
On Tue, 29 Jul 2003, John Bowler wrote:
> I meant that using __cdecl for the static library and __stdcall for the DLL
> *does* work and causes minimal problems. I didn't mean to imply that it is
> possible to fabricate a call to a __stdcall function using __cdecl or vice
> versa.
NOT minimal problems.
People compile the static library, they see it working, then they build
the DLL without changing anything, and that's working, too. That's
because the DLL and the test programs (example.c and minigzip.c) are
compiled, like the rest of the lib, with the same options, namely with
__cdecl. All the tests work, and nobody guesses that, according to your
policy, the DLL is incorrectly build. It will only crash when linked to
someone else's app compiled with stdcall.
This is what we have in zlib-1.1.4 and earlier, this is why we, as
makers of libpng and users of zlib.dll, waisted a long time to figure
out what is not working, this is why mutually-incompatible builds of
zlib.dll are circulating (because some people thought of enabling the
macro that enables stdcall, while others didn't), ..., ..., and this is
what we have to fix.
> ZEXTERN int ZEXPORT deflate(z_stream *strm, int flush);
>
> #define ZEXPORT __cdecl
> compiler produces symbol: _deflate
> #define ZEXPORT __stdcall
> compiler produces symbol: deflate at 8
>
> (or something like that). It is *impossible* for code compiled with one
> calling convention to accidentally call code compiled with a different
> convention, there will be a missing symbol at link time.
(1) C programmers don't have to know the fancy ways of decorating the
function names. If they get link-time errors, they wonder why it's
happending, even though they included all the appropriate source files
in the project...
(2) I said "if" they get link-time errors. When it happens to import the
undecorated name from the DLL implib, then you don't get link-time
errors any more. You get run-time crashes, and if you are unaware of
this very low-level issue (which can happen to virtually any non
ASM-savy programmers) then you are again clueless.
> What I'm trying to say here is that it doesn't matter very much what
> calling convention is used just so long as it is explicitly set in the
> zlib.h header file (probably via zconf.h).
Not always true. In particular, if you have callbacks, there is no way
to avoid the calling convention dirt in the users' sources.
This is not a problem in zlib, because the zlib callbacks are not
decorated with ZEXPORT, but this is yet another argument against using
any explicit convention in general (in addition to the problems of using
zlib in other programming languages, that I mentioned previously).
So what's the standard?
- __stdcall is the standard in Windows API functions.
(and Windows APIs don't have to be tied to C, so that may be
understandable)
- __cdecl is the standard in C functions.
- __cdecl is also the standard in the foreign languages that want to
access C functionality via C interfacing.
and
- zlib is not part of Windows API, and it does not offer "Windows"
functionality. It offers "C" functionality.
Cosmin
More information about the Zlib-devel
mailing list