通过 Boost Python 将 Python 函数转换为 C++,用作回调
Convert Python function to C++, via Boost Python, for use as a callback
一般来说,通过 Boost-Python 传递 Python 函数以便稍后在 C++ 代码中使用(即作为 C++ 对象中的回调)的推荐方法是什么?
更具体地说,我有一个 C++ class FooCPP
,我已经通过 Boost-Python 成功地暴露给 Python;用户与 Python class Foo
交互,后者在后台运行 C++ 对应项。人为的例子:
# 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 and -- and I'm familiar with the Boost-Python docs,但还没找到好的solution/explanation。提前致谢!
注释:C++11,boost v1.58.0,ubuntu16.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
签名应该是什么? IE。传入的 cpp_callback
定义了什么类型?
BOOST_PYTHON_MODULE
代码是否需要为此回调仿函数更改?
在 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_;
};
一般来说,通过 Boost-Python 传递 Python 函数以便稍后在 C++ 代码中使用(即作为 C++ 对象中的回调)的推荐方法是什么?
更具体地说,我有一个 C++ class FooCPP
,我已经通过 Boost-Python 成功地暴露给 Python;用户与 Python class Foo
交互,后者在后台运行 C++ 对应项。人为的例子:
# 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 and
注释:C++11,boost v1.58.0,ubuntu16.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
签名应该是什么? IE。传入的 cpp_callback
定义了什么类型?
BOOST_PYTHON_MODULE
代码是否需要为此回调仿函数更改?
在 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_;
};