Calling C++ functions from C
-
I am creating an internal app framework (for company apps). Using C++ will facilitate my task but I have to make the framework / library usable for C programmers. Any ideas?
use extern "C" into fn prototypes (of course they can't be class members) t! .h: #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int my_fn(void); #ifdef __cplusplus } #endif /* __cplusplus */
-
use extern "C" into fn prototypes (of course they can't be class members) t! .h: #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int my_fn(void); #ifdef __cplusplus } #endif /* __cplusplus */
-
Thats it! Thanks. I thought I had to specify function call argument passing (__cdecl, __fastcall, etc) just as Dr John Maddock's Regex++ library.
It's often a good idea to be specific about the calling convention when exporting from a DLL; if the client program is compiled with a different default convention (using the /Gd, /Gr or /Gz switches) from your DLL it either won't link correctly or will potentially crash at runtime, due to erroneous stack manipulations. __stdcall is marginally smaller (typically one ADD instruction) at the call site than __cdecl, but __cdecl can handle variable argument lists and is marginally smaller in the function implementation. The ADD instruction is used to reset the stack pointer after the call back to where it was before the compiler started PUSHing arguments. More info in John Robbins' excellent Debugging Applications books (I just bought the most recent one, Debugging Applications for Microsoft .NET and Microsoft Windows - there's a mouthful). This only applies to desktop Win32 running on IA32 processors; Windows CE on IA32 always uses __cdecl, while other processors only have a single calling convention. Most RISC processors use a calling convention sort of like __cdecl but with the first n arguments passed in registers. This is also true of AMD64 (first 4 arguments passed in RCX, RDX, R8, R9 or XMM0-3 if floating point) and IA64 (first 8 arguments passed in the rotating portion of the register file). [Yes, I know the processor names look a little unfamiliar; specifying 'x86' isn't very helpful any more because 64-bit 'x86-64' code works differently. AMD now wish Opteron/Athlon64-compatible code to be known as AMD64.] -- Mike Dimmick
-
It's often a good idea to be specific about the calling convention when exporting from a DLL; if the client program is compiled with a different default convention (using the /Gd, /Gr or /Gz switches) from your DLL it either won't link correctly or will potentially crash at runtime, due to erroneous stack manipulations. __stdcall is marginally smaller (typically one ADD instruction) at the call site than __cdecl, but __cdecl can handle variable argument lists and is marginally smaller in the function implementation. The ADD instruction is used to reset the stack pointer after the call back to where it was before the compiler started PUSHing arguments. More info in John Robbins' excellent Debugging Applications books (I just bought the most recent one, Debugging Applications for Microsoft .NET and Microsoft Windows - there's a mouthful). This only applies to desktop Win32 running on IA32 processors; Windows CE on IA32 always uses __cdecl, while other processors only have a single calling convention. Most RISC processors use a calling convention sort of like __cdecl but with the first n arguments passed in registers. This is also true of AMD64 (first 4 arguments passed in RCX, RDX, R8, R9 or XMM0-3 if floating point) and IA64 (first 8 arguments passed in the rotating portion of the register file). [Yes, I know the processor names look a little unfamiliar; specifying 'x86' isn't very helpful any more because 64-bit 'x86-64' code works differently. AMD now wish Opteron/Athlon64-compatible code to be known as AMD64.] -- Mike Dimmick