Конвертировать функцию Python в C ++ через Boost Python для использования в качестве обратного вызова - PullRequest
0 голосов
/ 06 июня 2018

В общем, каков рекомендуемый способ передачи функции 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 для этого функтора обратного вызова?

1 Ответ

0 голосов
/ 09 июня 2018

Реализация функтора в 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_;
};
...