Frage

How does one can use std::bind (not boost::bind) on __stdcall function or is it even possible in current implementation? When i try to compile following example:

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

or same but with declaring func as:

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

Gives me strange build output (which i included below). There is a very sick way to make it compile:

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));

But it won't let me call function like this (*proc)(0,0,0);. Which is sad. All this happens just because that func - myhook - declared as __stdcall. Offcourse i can just write a dirty assembly hack that will push 4 dwords at the end of func and this will "make" it __stdcall, but i'm not quite sure about this and also this is even more sicker way.

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>          ]
War es hilfreich?

Lösung

In current VS 2012 its not possible and anyway not applicable as solution to this problem. The idea was to bind member function and use it as Hook-procedure. That is not possible, as David Rodriguez and R. Martinho Fernandes (in chat - lounge-C++) mentioned, because std::bind produces object, not function and thus it's result can't be passed as argument to SetWindowsHookEx.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top