[gdal-dev] 1.4.4 Preliminary Win32 Binaries

Mateusz Loskot mateusz at loskot.net
Mon Nov 26 05:58:23 EST 2007


Even Rouault wrote:
> Hi,
>
> First, I found the following discussion on CPL_STDCALL problems  :
> http://www.nabble.com/Windows-linking-to-FWTools-gdal_i.lib-t1128647.html
>
> I think you pointed out exactly where your problem is.
>
> If you look at cpl_port.h, you can see :
>
> #ifndef CPL_STDCALL
> #if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL)
> #  define CPL_STDCALL     __stdcall
> #else
> #  define CPL_STDCALL
> #endif
> #endif
>
> So, libgdal compiled with GCC/MSYS will ignore CPL_STDCALL and export
> symbols as 'cdecl' without any symbol decoration.

Yes. cdecl is a default convention used in C programs, C Standard Library,
as well as in C++ global functions. However, __stdcall is usually faster,
so preferred when using Visual C++ (also used as default convention in
Win32 world).

> Whereas, libgdal14.dll compiled by Frank with MVSC 7.1  takes into account
> CPL_STDCALL  and exports these symbols with the _foo at X decorations.

Yes, as mangled name with X as encoded size of input arguments.

> Now, let's play a bit...
>
> I've tried to compile the following c code into a DLL with
> i586-mingw32msvc-gcc (under Linux) :
>
> foo.c :
> int __declspec(dllexport) foo_cdecl();
> int __declspec(dllexport) foo_cdecl() {}
> int __declspec(dllexport) __stdcall foo_stdcall();
> int __declspec(dllexport) __stdcall foo_stdcall() {}
>
> Compiled with "i586-mingw32msvc-gcc foo.c -shared -o foo.dll", I get the
> following symbols :
>
> [Ordinal/Name Pointer] Table
>         [   0] foo_cdecl
>         [   1] foo_stdcall at 0
>
> That confirms what is above. Except, that I would have
> expected "_foo_stdcall at 0" instead of "foo_stdcall at 0".

It's just how MinGW mangles function names. Simply, it does not prefix a
name, unlike Visual C++ where _ is used as a name prefix. Here is the
mangling schema explained:

http://msdn2.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx

> http://wyw.dcweb.cn/stdcall.htm which appears to be a great reference on
> that subject seems to confirm that GCC and MSVC don't decorate dllexport
> __stdcall symbols the same way...

Yes, and not only these two differ in this subject.
Almost all compilers use their own decoration patterns:

http://en.wikipedia.org/wiki/Name_mangling#How_different_compilers_mangle_the_same_functions

This is well-known part of so called DLL Hell :-)

Names mangling is a part of "type-safe linking" feature used by C++
compilers and linker. This feature makes it possible to overload functions
(class members, etc.), because it assures parameters are passed correctly.
When compilers build an object from a C++ class, all names
of member functions have to be encoded to include all information about
function prototype, return type, etc. to distinguish all overloaded
symbols.

The problem is that implementation of type-safe linking is not standardized
and different C++ compiler vendors implement it differently.
Therefore, there are many different mangling schemes.

One possible workaround is to use .DEF files and assign ordinals to
functions but even then we'll need to provide different
import libraries for different compilers/linkers.

http://msdn2.microsoft.com/en-us/library/d91k01sh(VS.80).aspx

> Now, I've written foo.def to export foo_stdcall at 0 as _foo_stdcall at 0:
> DESCRIPTION 'foo'
> VERSION 1.0
> EXPORTS
> foo_cdecl
> _foo_stdcall at 0 = foo_stdcall at 0
>
> i586-mingw32msvc-gcc foo.c -c
> i586-mingw32msvc-dllwrap --def foo.def -o foo.dll foo.o
>
> And now, I get :
>
> [Ordinal/Name Pointer] Table
>         [   0] _foo_stdcall at 0
>         [   1] foo_cdecl
>
> Great victory !

Unfortunately, it introduces another problem - huge maintenance overhead.
We will need to provide .DEF files per compiler, with names
mangled according to specific decoration schema used by particular compiler.

> So I guess that even if you change the above portion of cpl_port.h to #
> define CPL_STDCALL     __stdcall to recompile GDAL with gcc, you won't get
> something compatible, unless you use a DEF file and use alias symbols for
> all stdcall functions.

Yes.

> Arf, these calling conventions / different compiler
> issues are a nightmare !

The DLL Hell. And this is one of the important reasons why Component Object
Model (COM) was invented and has been used so widely in the Microsoft world.

Cheers
-- 
Mateusz Loskot
http://mateusz.loskot.net


More information about the gdal-dev mailing list