If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

[Solved] GCC, dynamic linking and calling conventions

Hello

I am trying to develop Windows application using DevCpp and GCC compiler v.3.2.4. Application uses mylib.dll library compiled with MSVC 7 and this causes the incompatibility problems. Some functions (almost all) at mylib.dll use __stdcall calling convention, while GCC compiler uses __cdecl by default. This behaviour can be changed globally using -mrtd switch.
Because of problems with linking MSVC dlls to GCC apps, I decided to link mylib.dll dynamically. Using LoadLibrary and GetProc Address I assign address of proc to function pointer, and call it in my program:

Now whats the question: Is there any way to force GCC compiler to call some functions pointed by pointers using __stdcall, and some others pointed by pointers and defined in program using __cdecl?

I was trying following things:
1. use -mrtd switch: works OK but only as long as my app calls ONLY __stdcall procs. When this option is used, app cannot correctly call functions from other GCC libs, as they use __cdecl.

2. do not use -mrtd switch, and declare function pointer as using __stdcall

Re: GCC, dynamic linking and calling conventions

It is possible to use _stdcall for some functions and _cdecl for others, there is no problem, even with static linking to DLL.

But you must be careful with the position of the _stdcall specifier:

Originally Posted by Hobson

Code:

typedef void (*__stdcall myfunc)(void); //doesnt work, function is still called as __cdecl

It defines a _stdcall pointer to a _cdecl function (what means that if you declare a global variable with this type, the global variable name will be mangled without underscore character), and not a pointer to a _stdcall function.
You must replace this declaration by

Code:

typedef void (__stdcall *myfunc)(void);

You don't need dynamic linking, instead you need a .def file to convert the VC style name mangling to GCC name mangling:

Code:

; .Def file
IMPORTS
func1@0=NameOfTheDll._func1@0 ; you should not use absolute dll path, but only the dll name.

You must pass the .def file to the linker or to gcc.exe or g++.exe if you use a single-step compilation (g++.exe automatically call the linker if the -c option is not used).
If you use DevCpp, you must go to Project menu/Project options menu item/parameters tab/linker text box, and enter the name of the .def file.

Re: GCC, dynamic linking and calling conventions

Originally Posted by Hobson

Hello

I am trying to develop Windows application using DevCpp and GCC compiler v.3.2.4. Application uses mylib.dll library compiled with MSVC 7 and this causes the incompatibility problems. Some functions (almost all) at mylib.dll use __stdcall calling convention, while GCC compiler uses __cdecl by default. This behaviour can be changed globally using -mrtd switch.

As SuperKoko pointed out, all you need to do is declare whatever function you want to declare as either __stdcall or __cdecl -- you don't need a global switch.

As far as I know, all Windows C++ compilers allow you to individually declare functions as either __stdcall or __cdecl.

But to be perfectly honest with you -- unless the compiler comes with a "lib" generating tool, where you can just take the DLL and make a compatible import library for the compiler (i.e. IMPLIB.EXE from Borland), I don't bother with figuring out def files, lib files, etc. Every compiler has their quirk as to how to implicitly link to a library, and I don't have the time or patience to figure out each one.

Instead I use LoadLibrary() and GetProcAddress() in a convenient class wrapper. Then there is no need to be fooling around with creating lib files, def files, and best of all, the link issues disappear (just make sure you declare your functions correctly). Not only that, the app will compile on any Windows compiler with little to no modifications.

Re: GCC, dynamic linking and calling conventions

Thanks guys for your replies.

Id like to stick to dynamic linking, and not to bother with all those files needed every time I switch compiler. Just DLL and source is what I want.
Unfortunately, none of methods mentioned by SuperKoko did not work. Declaring pointer as

Code:

void (_stdcall *myfunc)()

does not help, there is still a runtime error. After creating .def file with altered names linker complains about undefined reference.

Maybe there is something wrong with my code, I am going to look deeper into it.

Re: GCC, dynamic linking and calling conventions

Here are apps I am trying to make working. Both client and server suffer the same problem, but thats the server which crashes first (cant pass correctly even single loop). Both apps compiled with VS 6 work ok, but crash when compiled at DevCpp. I hope that all will be clear for you, but if source codes are just too much mess, leave it and dont waste your time, I will manage somehow.

And there is still some more issues, like not unloaded libraries and so on, but first id like to make calling stuff working.
Id like to keep main file modified as little as possible, since it should compile on both windows and linux using GCC.
Thanks a lot
Hob

I've done it so this is in a convenient class wrapper, but nothing stops you from doing this in just a straight procedural manner.

Using this method, this works universally across all Windows-based C++ compilers that I've come across. I've tried this with VC++ (all versions), GCC, Borland, CodeWarrior, Digital Mars, Intel C++, you name it. This is the advantage of just investing some time in creating the interface to the DLL at runtime instead of trying to figure out def files, lib files, import libraries, etc.

My company has to deal with different compilers and versions, and as stated before, trying to figure out how each one implicitly links DLL's was more of a time waster. It is far easier just to take code, compiling it, and just running it if we want to test one of our DLL's.

[Solved] GCC, dynamic linking and calling conventions

amagad, guys, I found a source of my problems. Here comes the explanation, as it could be useful for someone someday.

1. I declared my function pointers in following way:

Code:

typedef void (__stdcall *func)(void);

2. GCC defines __stdcall as

Code:

#define __stdcall __attribute__((__stdcall__))

3. And now, most funny part: 3rd party library I was using (Apache APR), defined:

Code:

#define __attribute__(__x)

So, __stdcall from my declarations just vanished.

That was lotta time I wasted for this and I was pretty sure that its not a compiler trouble, but couldnt find the reason of this strange GCC behavior. I managed to find the bug using -save-temps and digging thru 1.6MB of code :/