c++ - 我怎样才能 boost::bind 到传递并返回 std::string 的托管类的成员?

标签 c++ boost c++-cli boost-bind

我正在尝试做与 this 非常相似的事情但我正在努力将字符串传入/传出回调。

这是我尝试运行的代码的简化版本:

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

我忍不住觉得我几乎已经明白了,但我还缺少什么?

最佳答案

通过一些实验和对 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);
    }
};

关于c++ - 我怎样才能 boost::bind 到传递并返回 std::string 的托管类的成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42304020/

相关文章:

c++ - make 失败,返回错误 "cannot convert ‘std::istream {aka std::basic_istream<char>}’ 到 ‘bool’”

c++ - C++中数组char的初始化

c++ - boost.log 含义和作用

c# - 将非托管类型结构指针转换为托管类型结构指针

javascript - 性能 : NaCl vs Emscripten

c++ - double boost::bind 导致编译时错误

c++ - Boost线程完成回调可用

c# - 在 C++/CLI 中创建托管类和命名空间时出现问题

generics - 无法将 dynamic_cast 与泛型一起使用

c++ - MALLOC_CHECK_ 不报告违规