http.get_asyc("www.google.ca", [&](int a) { std::cout << "response recieved: " << a << std::endl; });
这是来自Python的:
^{pr2}$我已经设置了一个demo on Coliru,它精确地显示了我要完成的任务。下面是我得到的代码和错误:
#include <boost/python.hpp>
#include <boost/function.hpp>
struct http_manager
{
void get_async(std::string url, boost::function<void(int)> on_response)
{
if (on_response)
{
on_response(42);
}
}
} http;
BOOST_PYTHON_MODULE(example)
{
boost::python::class_<http_manager>("HttpManager", boost::python::no_init)
.def("get_async", &http_manager::get_async);
boost::python::scope().attr("http") = boost::ref(http);
}
import example
def f(r):
print r
example.http.get_async('www.google.ca', f)
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
Boost.Python.ArgumentError: Python argument types in
HttpManager.get_async(HttpManager, str, function)
did not match C++ signature:
get_async(http_manager {lvalue}, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::function<void (int)>)
我不知道为什么function
没有自动转换为boost::function
。在
我以前问过a vaguely similar question,得到了一个惊人的答案。我还想知道答案中类似的方法是否也适用于这个用例。在
非常感谢您的支持!在
当一个函数通过Boost.Python被调用,Boost.Python将查询注册表,根据所需的C++类型,为每个调用方的参数找到一个合适的Python转换器。如果找到一个转换器,它知道如何将Python对象转换为C++对象,那么它将使用转换器构造C++对象。如果没有找到合适的转换器,则Boost.Python将引发
ArgumentError
异常。在已注册from Python转换器:
int
和{boost::python::converter::registry::push_back()
测试可兑换性和构造对象的步骤分为两个不同的步骤。由于没有从Python converter为
boost::function<void(int)>
注册,Boost.Python将引发ArgumentError
异常。Boost.Python不会尝试构造boost::function<void(int)>
对象,尽管boost::function<void(int)>
可以从boost::python::object
构造。在要解决此问题,请考虑使用一个shim函数来延迟
boost::function<void(int)>
的构造,直到boost::python::object
通过Boost.Python图层:这是一个完整的例子demonstrating这种方法:
^{pr2}$交互式使用:
另一种方法是显式地为
boost::function<void(int)>
注册from Python转换器。这样做的好处是所有函数都通过Boost.Python可以使用转换器(例如,不需要为每个功能编写垫片)。但是,需要为每个C++类型注册一个转换。下面是一个示例demonstrating显式注册boost::function<void(int)>
和boost::function<void(std::string)>
的自定义转换器:一种解决方案是添加重载函数:
然后暴露这个特定的过载:
^{pr2}$或者,如果你不想用python的东西污染你的主类,那么你可以创建一个包装类。事情看起来也干净多了:
更新:另一个选择是使用python可调用的boost函数转换器。这将解决单例问题,并且不需要更改主类。在
相关问题 更多 >
编程相关推荐