一般来说,通过Boost-Python传递Python函数的推荐方法是什么,以便以后在C ++代码中使用(即作为C ++对象中的回调)?
更具体地说,我有一个C ++类FooCPP
,我通过Boost-Python成功地将其暴露给了Python;用户与运行C ++对应的Python类Foo
进行交互。举例:
# Foo.py
from foo_base import FooBase
class Foo(FooBase):
...
def callback(val=42.):
return val
foo = Foo()
foo.run(callback)
Boost Python绑定:
// foo_bindings.cpp
#include "foo.hpp"
#include <boost/python.hpp>
namespace bp = boost::python;
FooPython::Run(const bp::object& py_callback)
// TODO: Do something with the python callback to make it a C++ function!
std::function<double(double)> cpp_callback;
FooCPP::Run(cpp_callback);
)
BOOST_PYTHON_MODULE(foo_base){
bp::class_<FooPython>("FooBase")
.def("run", &FooPython::Run)
;
}
那么如何解决foo_bindings.cpp中的TODO注释?
我已经完成了许多相关的SO问题 - 例如pass python function to boost c和sending py function as boost function arg - 我熟悉Boost-Python docs,但没有找到一个好的解决方案/解释。提前谢谢!
注:C ++ 11,boost v1.58.0,ubuntu 16.04
我可能刚刚找到了一个解决方案,我可以在foo_bindings.cpp中实现一个仿函数,例如,
struct PythonCallback {
public:
PythonCallback(bp::object cb_func) : cb_func_(cb_func) {}
double operator() (const double& val) {
// Call the callback function in python
return cb_func_(val);
}
private:
bp::object cb_func_;
};
但那么FooCPP::Run
签名应该是什么?即为传递的cpp_callback
定义了什么类型?
此回调函数需要更改BOOST_PYTHON_MODULE
代码吗?
答案 0 :(得分:1)
在foo_bindings.cpp中实现一个仿函数,其中使用call调用回调:
#include <boost/python.hpp>
#include <boost/python/call.hpp>
struct PythonCallback : {
public:
PythonCallback(PyObject* func) : cb_(func) {}
double operator() (const double& value) {
// Call the callback function in python
return boost::python::call<double>(cb_, value);
}
private:
PyObject* cb_;
};