boost::python::def()
ドキュメントには、null以外の関数またはメンバー関数ポインターが提供された場合にのみdocstringを提供できることが記載されています。1つの解決策は、関数オブジェクト呼び出しを関数でラップすることです。
#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");
}
これにより、インタラクティブな使用法と同じ出力が生成されます。2つのアプローチの唯一の顕著な動作の違いは、最初の例では、に新しい値を割り当てることにより、実行時に基盤となる実装を変更できることfunc
です。