【问题标题】:Mixed calling conventions make compilation errors混合调用约定会导致编译错误
【发布时间】:2011-03-09 15:31:31
【问题描述】:

我有一个包含一些 API 函数的库 (C++)。其中之一被声明为 __cdecl,但从 __stdcall 获得一个函数指针。比如:

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

然后 - 我有一个使用此库的 C++ 可执行项目,但不调用上述 API 或使用 Func 类型。

Func的调用约定更改为__stdcall后,出现如下编译错误:

错误 C2995: 'std::pointer_to_unary_function<_arg> std::ptr_fun(_Result (__cdecl *)(_Arg))':函数 模板已经 定义 c:\program files\microsoft 视觉工作室 8\vc\include\functional

知道会是什么吗?

提前致谢!!

【问题讨论】:

    标签: c++ compiler-errors stdcall cdecl


    【解决方案1】:

    Err.. 它们不兼容。您必须在调用双方指定相同的调用约定。否则尝试调用会炸毁机器堆栈。

    【讨论】:

    • 我们可以在一个项目中混合调用约定吗?假设在默认情况下所有函数都是 __stdcall/WINAPI 的 MSVS/windows 上,我们是否可以让某些函数遵循不同的调用约定,比如 __fastcall(也许是为了提高性能)和其他一些 __thicall。那么一般情况下我们可以混合调用约定吗?
    • 只要签名中存在调用约定,当然可以。但这不是混合调用约定——被调用者和调用者会同意。
    • @BillyNNeal 是的,我的意思是对程序中的不同函数有不同的调用约定。所以这是可能的。嗯不错。谢谢。
    【解决方案2】:

    它们是兼容的,至少在 Windows 中(而在 Linux 中根本没有 __stdcall...) 问题是库错误地重新定义了 __stdcall 以与 Linux 兼容,如下所示:

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

    exe项目中包含了这个定义,__MYLIB_WIN32并没有在其中定义,而只是在库中。 将上述定义改为:

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

    一切正常。

    谢谢大家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 2012-10-22
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多