У меня просто есть объект функции:
boost::function<int(int)> func = /** ... **/;
И хочу выставить его на Python с помощью строки документации.
Но очевидное
def("func", func, "Some boring documentation goes here.");
Сбой с забавным сообщением ~ 2500 строк.
Есть идеи?
Редактировать: Я сделал другие тесты:
def("func", func); // doesn't compile
def("func",
make_function(
func,
default_call_policies(),
vector<int,int>()
)
); // compiles
def("func",
make_function(
func,
default_call_policies(),
vector<int,int>()
),
"Some boring documentation goes here"); // doesn't compile
boost::python::def()
в документации упоминается возможность предоставления строки документации только в том случае, если указана ненулевая функция или указатель на функцию-член. Один решение это обернуть вызов объекта функции в функцию:
#include <boost/function.hpp>
#include <boost/python.hpp>
int times_two(int x) { return x * 2; }
boost::function<int(int)> func = ×_two;
int times_two_wrap(int x) { return func(x); }
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("times_two", ×_two_wrap,
"returns two times the supplied value");
}
Интерактивное использование:
>>> import example
>>> assert(6 == example.times_two(3))
>>> print help(example.times_two)
times_two( (int)arg1) -> int :
returns two times the supplied value
C++ signature :
int times_two(int)
>>>
Boost.Python имеет несколько уровней API. Самый высокий уровень в основном документирован, но он использует менее документированный низкоуровневый API. В этом конкретном случае, похоже, что высокоуровневый API плохо перенаправляет на низкоуровневый API. Вместо этого можно создать функцию Python, используя boost::python::make_function()
, затем используйте нижний уровень boost::python::objects::add_to_namespace()
функционировать, как продемонстрировал ниже:
#include <boost/function.hpp>
#include <boost/python.hpp>
int times_two(int x) { return x * 2; }
boost::function<int(int)> func = ×_two;
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
// Wrap the functor in a Python object.
python::object py_func = python::make_function(
func,
python::default_call_policies(),
boost::mpl::vector<int, int>());
// Add the function directly to the namespace.
python::objects::add_to_namespace(
python::scope(), // current namespace,
"times_two", // function name,
py_func, // function,
"returns two times the supplied value");
}
Это дает тот же результат с интерактивным использованием. Единственное заметное поведенческое различие между этими двумя подходами состоит в том, что первый пример позволяет изменить базовую реализацию во время выполнения, назначив новое значение func
,
Других решений пока нет …