2017-02-17 105 views
0

我試圖做一些非常類似於this的東西,但我很努力地將字符串傳遞給回調函數。我該如何boost ::綁定到一個託管類的成員,它傳遞並返回一個std :: string?

這是代碼的削減版本,我試圖運行:

using namespace System; 
using namespace System::Runtime::InteropServices; 

#pragma unmanaged 

// The unmanaged boost function prototype the native library wants to bind to 
typedef boost::function<std::string(const std::string&)> MyNativeCallback; 

// The unmanaged library I'm trying to wrap 
class MyUnmanagedClass 
{ 
    public: 
     MyUnmanagedClass() {} 

     void RegisterCallback(MyNativeCallback callback); 
}; 

// Taken from here: https://stackoverflow.com/questions/163757/how-to-use-boostbind-in-c-cli-to-bind-a-member-of-a-managed-class 
typedef std::string(__stdcall *ChangeCallback)(std::string); 
public delegate std::string ChangeHandler(std::string); 

#pragma managed 

// The managed callback we'll eventually trigger if all this works. 
public delegate String^ ManagedHandler(String^); 

// A managed wrapper to bridge the gap and provide a managed call in response to the unmanaged callback 
public ref class MyManagedClass 
{ 
protected: 

    MyUnmanagedClass* m_responder; 

public: 
    event ManagedHandler^ OnChange; 

public: 
    MyManagedClass(): 
     m_responder(new MyUnmanagedClass()) 
    { 
     // Example code I'm trying to adapt from here: https://stackoverflow.com/questions/163757/how-to-use-boostbind-in-c-cli-to-bind-a-member-of-a-managed-class 
     ChangeHandler^ handler = gcnew ChangeHandler(this, &MyManagedClass::HandleRequest); 
     GCHandle gch = GCHandle::Alloc(handler); 
     System::IntPtr ip = Marshal::GetFunctionPointerForDelegate(handler); 
     ChangeCallback cbFunc = static_cast<ChangeCallback>(ip.ToPointer()); 

     MyNativeCallback handlerToBind = boost::bind(cbFunc, _1); // <-- This fails with 'error C2825' 
     m_responder->RegisterCallback(handlerToBind); 
    } 

    std::string HandleRequest(std::string s) 
    { 
     OnChange(nullptr); 
     return nullptr; 
    } 
}; 

...使我有以下錯誤:

1>C:\boost_1_55_0\boost/bind/bind.hpp(69): error C2825: 'F': must be a class or namespace when followed by '::' 
1>   C:\boost_1_55_0\boost/bind/bind_template.hpp(15) : see reference to class template instantiation 'boost::_bi::result_traits<R,F>' being compiled 
1>   with 
1>   [ 
1>    R=boost::_bi::unspecified, 
1>    F=std::basic_string<char,std::char_traits<char>,std::allocator<char>> (__stdcall *)(std::string) 
1>   ] 
1>   c:\projects\zephir-git\zephirsoftware-gitlab\lcufirmware\managedzeromqdataforwarding\Responder.h(54) : see reference to class template instantiation 'boost::_bi::bind_t<R,F,L>' being compiled 
1>   with 
1>   [ 
1>    R=boost::_bi::unspecified, 
1>    F=std::string (__stdcall *)(std::string), 
1>    L=boost::_bi::list1<boost::arg<1>> 
1>   ] 
1>C:\boost_1_55_0\boost/bind/bind.hpp(69): error C2039: 'result_type' : is not a member of '`global namespace'' 
1>C:\boost_1_55_0\boost/bind/bind.hpp(69): error C2146: syntax error : missing ';' before identifier 'type' 
1>C:\boost_1_55_0\boost/bind/bind.hpp(69): error C2208: 'boost::_bi::type' : no members defined using this type 
1>C:\boost_1_55_0\boost/bind/bind.hpp(69): fatal error C1903: unable to recover from previous error(s); stopping compilation 

我不禁感慨我幾乎得到了這個,但有一些我錯過了?

回答

1

解決了它的一些實驗和一些更詳細的檢查the docs on different forms of bind

這是所得到的代碼按預期方式工作:

using namespace System; 
using namespace System::Runtime::InteropServices; 

#pragma unmanaged 

// The unmanaged boost function prototype the native library wants to bind to 
typedef boost::function<std::string(const std::string&)> MyNativeCallback; 

// The unmanaged library I'm trying to wrap 
class MyUnmanagedClass 
{ 
    public: 
     MyUnmanagedClass() {} 

     void RegisterCallback(MyNativeCallback callback); 
}; 

typedef std::string(__stdcall *ChangeCallback)(std::string); 
public delegate std::string ChangeHandler(std::string); 

#pragma managed 

// The managed callback we'll eventually trigger if all this works. 
public delegate std::string ManagedHandler(const std::string&); 

// A managed wrapper to bridge the gap and provide a managed call in response to the unmanaged callback 
public ref class MyManagedClass 
{ 
protected: 

    MyUnmanagedClass* m_responder; 

public: 
    event ManagedHandler^ OnChange; 

public: 
    MyManagedClass(): 
     m_responder(new MyUnmanagedClass()) 
    { 
     // Example code I'm trying to adapt from here: http://stackoverflow.com/questions/163757/how-to-use-boostbind-in-c-cli-to-bind-a-member-of-a-managed-class 
     ChangeHandler^ handler = gcnew ChangeHandler(this, &MyManagedClass::HandleRequest); 
     GCHandle gch = GCHandle::Alloc(handler); 
     System::IntPtr ip = Marshal::GetFunctionPointerForDelegate(handler); 
     ChangeCallback cbFunc = static_cast<ChangeCallback>(ip.ToPointer()); 

     MyNativeCallback handlerToBind = boost::bind<std::string>(cbFunc, _1); 
     m_responder->RegisterCallback(handlerToBind); 
    } 

    std::string HandleRequest(const std::string& s) 
    { 
     return OnChange(s); 
    } 
}; 
+0

同樣的方法適用於標準::功能和std ::綁定。 – user3717478

相關問題