В общем, каков рекомендуемый способ передачи функции Python через Boost-Python для последующего использования в коде C ++ (т. Е. В качестве обратного вызова в объекте C ++)?
В частности, у меня есть класс C ++FooCPP
, что я успешно выставил Python через Boost-Python;пользователь взаимодействует с классом Python 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)
;
}
Итак, как мне обратиться к комментарию TODO в foo_bindings.cpp?
Я ушелчерез ряд связанных с этим вопросов SO - например, передать функцию python для повышения c и отправив функцию py в качестве функции повышения arg - и я знаком с Boost-Python docs , но не нашел хорошего решения / объяснения.Заранее спасибо!
Примечания: C ++ 11, boost v1.58.0, ubuntu 16.04
Обновление
Возможно, я только что нашел решение, в котором я могу реализоватьfunctor в 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
для этого функтора обратного вызова?