繁体   English   中英

使用std :: bind与__stdcall函数

[英]Using std::bind with __stdcall function

如何在__stdcall函数上使用std :: bind(而不是boost :: bind),或者在当前实现中甚至有可能? 当我尝试编译以下示例时:

std::function<LRESULT __stdcall(int, WPARAM, LPARAM)> func;
func = std::bind(&EventListener::myhook, this, std::placeholders::_1, 
                 std::placeholders::_2, std::placeholders::_3);

或相同,但将func声明为:

std::function<LRESULT(int, WPARAM, LPARAM> func;

给我奇怪的构建输出(我在下面包括了)。 有一种非常糟糕的方法可以进行编译:

decltype(std::bind(&EventListener::myhook, nullptr, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))* HookCallbackPointer;
    HookCallbackPointer proc;

proc = reinterpret_cast<HookCallbackPointer>
    (&std::bind(&EventListener::myhook, this,
                std::placeholders::_1,
                std::placeholders::_2,
                std::placeholders::_3));

但这不会让我调用这样的函数(* proc)(0,0,0);。 真伤心 发生所有这些仅仅是因为该函数-myhook-声明为__stdcall。 当然,我可以编写一个肮脏的汇编技巧,该技巧将在func的末尾推送4个双字,这将“使它成为__stdcall”,但是我对此不太确定,这也是一种更恶心的方法。

1>D:\bin\Visual Studio\VC\include\xrefwrap(431): error C2440: 'return' : cannot convert from 'std::_Do_call_ret<_Forced,_Ret,_Funx,_Btuple,_Ftuple>::type' to 'LRESULT'
1>          with
1>          [
1>              _Forced=false,
1>              _Ret=void,
1>              _Funx=__w64 long (__stdcall EventListener::* )(int,WPARAM,LPARAM),
1>              _Btuple=std::tuple<EventListener *,std::_Ph<1>,std::_Ph<2>,std::_Ph<3>>,
1>              _Ftuple=std::tuple<int &,WPARAM &,LPARAM &,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          Expressions of type void cannot be converted to other types
1>          D:\bin\Visual Studio\VC\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<_Ty>::_ApplyX<_Rx,int,__w64 unsigned int,__w64 long>(_V0_t &&,_V1_t &&,_V2_t &&)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Rx=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<_Ty>::_ApplyX<_Rx,int,__w64 unsigned int,__w64 long>(_V0_t &&,_V1_t &&,_V2_t &&)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Rx=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(239) : while compiling class template member function 'LRESULT std::_Func_impl<_Callable,_Alloc,_Rx,_V0_t,_V1_t,_V2_t>::_Do_call(_V0_t &&,_V1_t &&,_V2_t &&)'
1>          with
1>          [
1>              _Callable=_MyWrapper,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>,
1>              _Rx=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(516) : see reference to class template instantiation 'std::_Func_impl<_Callable,_Alloc,_Rx,_V0_t,_V1_t,_V2_t>' being compiled
1>          with
1>          [
1>              _Callable=_MyWrapper,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>,
1>              _Rx=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(516) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(516) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(516) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>>>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(516) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>>>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Alloc=std::allocator<std::_Func_class<LRESULT,int,WPARAM,LPARAM>>
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(692) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Reset<_Ty>(_Fty &&)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          D:\bin\Visual Studio\VC\include\functional(692) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t,_V1_t,_V2_t>::_Reset<_Ty>(_Fty &&)' being compiled
1>          with
1>          [
1>              _Ret=LRESULT,
1>              _V0_t=int,
1>              _V1_t=WPARAM,
1>              _V2_t=LPARAM,
1>              _Ty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>,
1>              _Fty=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          main.cpp(27) : see reference to function template instantiation 'std::function<_Fty> &std::function<_Fty>::operator =<std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>>(_Fx &&)' being compiled
1>          with
1>          [
1>              _Fty=LRESULT (int,WPARAM,LPARAM),
1>              _Forced=false,
1>              _Ret=void,
1>              _Fun=LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),
1>              _V0_t=EventListener *const ,
1>              _V1_t=std::_Ph<1> &,
1>              _V2_t=std::_Ph<2> &,
1>              _V3_t=std::_Ph<3> &,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fx=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]
1>          main.cpp(27) : see reference to function template instantiation 'std::function<_Fty> &std::function<_Fty>::operator =<std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>>(_Fx &&)' being compiled
1>          with
1>          [
1>              _Fty=LRESULT (int,WPARAM,LPARAM),
1>              _Forced=false,
1>              _Ret=void,
1>              _Fun=LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),
1>              _V0_t=EventListener *const ,
1>              _V1_t=std::_Ph<1> &,
1>              _V2_t=std::_Ph<2> &,
1>              _V3_t=std::_Ph<3> &,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil,
1>              _Fx=std::_Bind<false,void,LRESULT (__stdcall EventListener::* )(int,WPARAM,LPARAM),EventListener *const ,std::_Ph<1> &,std::_Ph<2> &,std::_Ph<3> &,std::_Nil,std::_Nil,std::_Nil>
1>          ]

在当前的VS 2012中,它不可能并且无论如何都不适用于解决此问题。 这个想法是绑定成员函数并将其用作Hook过程。 正如David Rodriguez和R.Martinho Fernandes(在聊天室-C ++)中提到的那样,这是不可能的,因为std :: bind生成对象而不是函数,因此其结果不能作为参数传递给SetWindowsHookEx。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM