Я пытаюсь узнать о функциях Boost. Я хочу передать функцию Python в модуль C++, завернутый с помощью Boost Python. Я выполнил приведенный здесь пример и изменил его, чтобы принять функции, которые принимают входной аргумент и возвращают некоторый вывод. Вот мой код:
typedef double (op_t)(double);
boost::function<op_t> op;
double defaultOperator(double t) {
return t;
}
void setOperator(boost::python::object obj) {
op = obj;
}
double callOperator(double t) {
return op(t);
}
BOOST_PYTHON_MODULE(op1) {
op = &defaultOperator;
def("setOperator", &setOperator);
def("callOperator", &callOperator);
}
Когда я пытаюсь скомпилировать это, я получаю сообщение об ошибке в моей функции setOperator
которая говорит, что cannot convert 'boost::python::api::object to 'double in return
. Код работает, если я заменю строку typedef void (op_t)(double);
и измените callOperator
чтобы вернуть void. Это позволяет мне передавать функции Python, которые могут работать с аргументами, но ничего не возвращать.
Что не так в моем коде? Как мне исправить это, чтобы передать функцию Python, которая возвращает значение?
После большого поиска и некоторых проб и ошибок, мне удалось изменить свой код, чтобы он работал. Я должен был создать структуру-оболочку для объекта Boost Python, который включал метод operator()
, чтобы затем обернутый объект мог быть отличен в качестве функции увеличения, прежде чем назначить переменную op
. Здесь измененный код:
struct op_wrapper_t {
op_wrapper_t( object callable ) : _callable( callable ) {}
double operator()(double t) {
return extract<double>(_callable(t));
}
object _callable;
};
void setOperator(object obj) {
op = boost::function<double (double)>( op_wrapper_t(obj) );
}
Я следовал той же процедуре, что и в этом посте. Тем не менее, я до сих пор не понимаю, почему такая оболочка/кастинг не нужна для функций, которые возвращают void.