2012-11-08 98 views
3

如何在__stdcall函數上使用std :: bind(而不是boost :: bind),或者在當前的實現中甚至可以使用它? 當我試圖編譯下面的例子:使用std :: bind和__stdcall函數

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);.這是可悲的。 所有這些都是因爲func - myhook - 聲明爲__stdcall而發生的。 Offcourse我可以寫一個骯髒的大會黑客,將在func結束時推動4個dword,這將「使」它__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>   ] 
+2

您認爲'std :: bind'的結果是'std :: function '。編譯器似乎並不同意這一點。標準說這個類型是未指定的,那麼你怎麼知道它會是什麼? –

+2

擴展了Bo說的,而最終調用的函數是'__stdcall',綁定的對象將有一個'operator()',不必是'__stdcall'。我真的不知道在std :: bind中是否處理這個方法,但我不希望綁定對象是'__stdcall'(即'operator()'的調用約定和執行的調用內部不需要匹配) –

回答

3

在當前的VS 2012的不可能的,反正不適用的解決這個問題。 這個想法是綁定成員函數並將其用作Hook-procedure。這是不可能的,正如David Rodriguez和R. Martinho Fernandes(在chat-lounge-C++中)提到的那樣,因爲std :: bind產生對象,而不是函數,因此它的結果不能作爲參數傳遞給SetWindowsHookEx。