2

I have a library (C++) which has some API functions. One of them is declared as __cdecl, but gets a function poiner from __stdcall. Something like:

typedef  int (__stdcall *Func)(unsigned char* buffer);
//...
int ApiFunc(Func funcPtr); //This is __cdecl since it is an 'extern "C"' library and the calling convention is not specified

Then - I have a C++ executable project which uses this library, but doesn't call the above API or uses the Func type.

After changing the calling convention of Func to __stdcall, I get the following compilation error:

error C2995: 'std::pointer_to_unary_function<_Arg,_Result,_Result(__cdecl *)(_Arg)> std::ptr_fun(_Result (__cdecl *)(_Arg))' : function template has already been defined c:\program files\microsoft visual studio 8\vc\include\functional

Any idea what could it be?

Thanks in advance!!

Allen L
  • 127
  • 1
  • 11

2 Answers2

2

Err.. they're incompatible. You have to specify the same calling convention on both sides of the call. Otherwise attempting to call will blow up the machine stack.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • Could we mix calling conventions though across a project? Say on MSVS/windows where all functions are __stdcall/WINAPI by default, could we make some function follow a different calling convention, say __fastcall (perhaps to improve performance) and some others __thicall. So in general can we mix calling conventions? – KeyC0de Sep 28 '18 at 00:12
  • 1
    As long as the calling convention is present in the signature, sure. But that's not mixing calling convention -- callee and caller would agree. – Billy ONeal Sep 29 '18 at 01:02
  • @BillyNNeal Yeah, I only meant having different calling conventions for different functions across a program. So that's possible. Ok, cool. Thanks. – KeyC0de Sep 29 '18 at 01:04
2

They ARE compatible, in Windows at least (and in Linux there isn't __stdcall at all...) The problem was that by mistake, the library re-defined __stdcall for compatibility with Linux, as:

#ifndef __MYLIB_WIN32
//Just an empty define for Linux compilation
#define __stdcall
#endif

The exe project includes this definition, and __MYLIB_WIN32 was not defined in it, but in the library only. Changing the above definition to:

#ifndef WIN32
//Just an empty define for Linux compilation
#define __stdcall
#endif

and everything works fine.

Thank you all.

Allen L
  • 127
  • 1
  • 11