2012-11-08 5 views
3

__stdcall 함수에 std :: bind (boost :: bind가 아닌)를 사용하거나 현재 구현에서 어떻게 사용할 수 있습니까? 난 다음 예제 컴파일 할 때 :__stdcall 함수를 사용하여 std :: 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)); 

는하지만 그것은 나를 (0,0,0)이 (* PROC)와 같은 함수를 호출 못하게 ;. 어느 것이 슬픈가. 이 모든 것은 func - myhook -이 __stdcall로 선언 되었기 때문에 발생합니다. Offcourse 난 func의 끝에 4 dwords을 밀 것이다 더러운 어셈블리 해킹을 쓸 수 있으며,이 "__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

궁극적으로 호출되는 함수는'__stdcall'이지만, 바인딩 된 객체는'__stdcall' 일 필요가없는'operator()'를 가질 것입니다. 나는 이것이 실제로'std :: bind'에서 어떻게 다루어 지는지 모르지만, 바인딩 된 객체가'__stdcall' (즉,'operator()'의 호출 규칙과 수행되는 호출을 기대하지 않을 것입니다 내부적으로 일치하지 않아도 됨) –

답변

3

현재 VS 2012에서는 불가능하며 어쨌든이 문제의 해결 방법으로는 적용 할 수 없습니다. 아이디어는 멤버 함수를 바인딩하여 Hook-procedure로 사용하는 것이 었습니다. David Rodriguez와 R. Martinho Fernandes (chat - lounge-C++)에서 언급했듯이 std :: bind는 함수가 아니라 객체를 생성하므로 결과를 SetWindowsHookEx에 인수로 전달할 수 없기 때문에 가능하지 않습니다.