Using std::bind with __stdcall function
c++, c++11, stdbind, stdcall
Solution
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.
Problem
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> ] ```