【发布时间】:2013-01-31 13:01:09
【问题描述】:
以下编译并使用 mingw 4.7.2 和 -m64 标志运行良好。
但使用 -m32 或任何 mingw 32 位版本无法编译。是错误还是我缺少编译器标志?
#include <iostream>
#include <functional>
using namespace std;
int __cdecl ccall(int i)
{
cout << i << endl;
return 0;
}
int __stdcall stdcall(int i)
{
cout << i << endl;
return 0;
}
int __fastcall fastcall(int i)
{
cout << i << endl;
return 0;
}
int main() {
std::function<int(int)> fnc = ccall;
fnc(10);
std::function<int(int)> fnstd = stdcall;
fnstd(100);
std::function<int(int)> fnfast = fastcall;
fnfast(200);
return 0;
}
错误信息:
...\Local\Temp\cc4ekW9J.s: Assembler messages:
...\Local\Temp\cc4ekW9J.s:30: Error: symbol `__ZNSt17_Function_handlerIFiiEPFiiEE9_M_invokeERKSt9_Any_datai' is already defined
...\Local\Temp\cc4ekW9J.s:80: Error: symbol `__ZNSt14_Function_base13_Base_managerIPFiiEE10_M_managerERSt9_Any_dataRKS4_St18_Manager_operation' is already defined
...\Local\Temp\cc4ekW9J.s:114: Error: symbol `__ZNSt14_Function_base13_Base_managerIPFiiEE10_M_managerERSt9_Any_dataRKS4_St18_Manager_operation' is already defined
在将调用“隐藏”在 lambda 函数中之后,我最终这样做了,它工作得很好:
template<class Ret, class... Args> class StdCall
{
public:
typedef Ret(__stdcall Fn_t)(Args...);
typedef std::function<Ret (Args...)> Functor_t;
Functor_t get(Fn_t pFn)
{
return [pFn](Args... as){
return pFn(as...);
};
}
};
auto fn1 = CdeclCall<int,int>().get( ccall );
auto fn2 = StdCall<int,int>().get( stdcall );
fn1(123);
fn2(156);
【问题讨论】:
-
请注意,这个调用约定是非标准的
-
在 64 位机器上只有
__fastcall。这就是它适用于 64 位编译的原因。__stdcall和__cdecl会被 x64 编译器简单地忽略。 -
使用
std::function<int __stdcall (int)> fnstd = stdcall;和std::function<int __fastcall (int)>会有帮助吗? -
坦克为你解答。但编译器不喜欢这种语法:错误:变量'std::function
fnstd'有初始化程序但类型不完整我最终这样做了:模板 类 StdCall { public: typedef Ret(__stdcall Fn_t)(Args...); typedef std::function Functor_t; Functor_t get(Fn_t pFn) { return [pFn](Args... as){ return pFn(as...); }; } }; auto fn1 = CdeclCall ().get(ccall); auto fn2 = StdCall ().get(stdcall); fn1(123); fn2(156); -
对于那些乱七八糟的评论感到抱歉。我用我的“解决方案”编辑了我的初始帖子
标签: c++ mingw std-function stdcall cdecl