通过 Boost Python 将 Python 函数转换为 C++,用作回调

Convert Python function to C++, via Boost Python, for use as a callback

本文关键字:Python C++ 回调 转换 Boost 函数 通过      更新时间:2023-10-16

一般来说,通过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问题 - 例如传递python函数来提升c和发送py函数作为boost函数arg - 我熟悉Boost-Python文档,但没有找到一个好的解决方案/解释。提前感谢!

注释: 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代码?

在 foo_bindings.cpp 中实现一个函子,其中回调通过调用调用

#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_;
};