C Interoperability on Windows -- or __cdecl, __stdcall, __fastcall
Brian Dessent
brian@dessent.net
Tue Aug 7 20:21:00 GMT 2007
Tobias Burnus wrote:
> on the GNU-Fortran@googlegroups list (gfortran user list) there was the
> question how to access the Windows' ABI function from Fortran.
>
> Using the ISO C Bindings helps in principle, but Windows has another
> speciality: It uses the __stdcall calling conventions whereas gfortran
> uses the __cdecl, calling convention. Cf.
> http://www.codeproject.com/cpp/calling_conventions_demystified.asp
>
> The question is now: How to tell the compiler to generate a call to a C
> function using this special calling convention?
>
> Lahey seemingly has a "DLL_IMPORT FunctionName" statement, one could
> also enhance BIND(c [, name=...]) by a
> "callingconvention="[cdecl,stdcall,fastcall]", or ?
>
> What do you think?
It can get even wackier than that, since all the operating system
provided Win32 API functions use stdcall calling convention but *don't*
have stdcall function name decorations. This is a bit of a red herring
though because the w32api import libraries provide the necessary
aliases, so the linker is able to patch things up. (I think this
madness all comes about from maintaining decades of binary backwards
compatibility or something. It was all flushed from the x64 version of
Windows, thankfully.)
It's also not true that stdcall is a hard and fast rule used for
everything on Windows. In the generic sense, the calling convention is
part of a library's ABI design, and is totally up to the designer what
calling convention to use. The information is supposed to be
encapsulated in the library's header files so that the user doesn't need
to know or care, just include the proper header which declare the
functions with the proper attributes.
If you look at the w32api header files most all functions are declared
as type WINAPI. Technically this "WINAPI" designation means use the
default calling convention of the platform, which is defined as
__attribute__((__stdcall__)) for all 32 bit x86 versions of Windows, but
it's actually cdecl for Windows CE and something else for x64 and
Itanium versions of Windows. And this 'WINAPI' convention really only
applies in the context of the Win32 API -- a user/vendor library/DLL can
use whatever the author wants.
Anyway, the real point I am driving at is that this information is
already encoded in the C header file for the function, so the ideal way
of dealing with this problem would be for the user to be able to say
"get the declaration of this function from this header file." This also
solves the problem of getting the arguments or struct layouts wrong,
etc. From a practical standpoint I don't know how realistic it is to
expect the fortran front-end to have the ability to parse a C header
file or access the results of such a parse, so being able to explicitly
specify a calling convention would probably be a logical addition to
bridge the gap. But in a sense it's cheating, as it's duplicating
information and requiring the user to know internal details of the
platform and/or library they are calling.
Brian
More information about the Fortran
mailing list