我怎样才能 boost::bind 到一个托管 class 的成员,它通过 returns 一个 std::string?
How can I boost::bind to a member of a managed class which passes and returns a std::string?
我正在尝试做一些与 this 非常相似的事情,但我正在努力将字符串 to/from 传递给回调。
这是我正在尝试的代码的精简版 运行:
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:
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:
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:
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);
}
};
我正在尝试做一些与 this 非常相似的事情,但我正在努力将字符串 to/from 传递给回调。
这是我正在尝试的代码的精简版 运行:
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:
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:
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:
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);
}
};