boost::python::object
stanowi ogólny interfejs do obiektów Pythona. Aby skonstruować jeden z PyObject*
, należy najpierw zbudować boost::python::handle<>
, który jest w zasadzie inteligentnym wskaźnikiem zaprojektowanym do zarządzania obiektami Pythona zliczanymi z odwołaniem (PyObject*
lub typami pochodnymi). Często używa się handle<>
między granicą między kodem wyższego poziomu Boost.Python i Python/C API.
namespace python = boost::python;
PyObject* py_object = get_py_object();
python::handle<> handle(py_object);
boost::python object(handle);
Zauważ, że handle
podzieli własność PyObject*
, a podczas zniszczenia, będzie to zmniejszyć liczbę odwołań na PyObject
ta zarządza. Dlatego w trakcie budowy ważne jest, aby określić, czy handle<>
potrzebuje zwiększyć liczbę referencyjną o PyObject*
.
Jeśli PyObject
miał już jej Ilość referencyjna wzrosła, a następnie użyć:
namespace python = boost::python;
PyObject* py_object = ...;
python::handle<> handle(py_object);
python::object object(handle);
Jeśli PyObject
nie miał jej Ilość referencyjna wzrosła, a uchwyt musi to zrobić, a następnie użyj funkcji borrowed()
podczas budowy:
namespace python = boost::python;
PyObject* py_object = ...;
python::handle<> handle(python::borrowed(py_object));
python::object object(handle);
Powyżej znajduje się pełna przykład demonstrating konstruowania boost::python::object
od A PyObject*
:
#include <vector>
#include <boost/python.hpp>
// Mocks...
enum { NPY_FLOAT };
typedef int npy_intp;
PyObject* PyArray_SimpleNewFromData(int, npy_intp*, int, void*)
{
return PyString_FromString("hello world");
}
boost::python::object build_day(int year, int day)
{
const int HEIGHT = 5;
const int WIDTH = 5;
std::vector<std::vector<float> > array(
WIDTH, std::vector<float>(HEIGHT));
npy_intp dims[2] = {WIDTH, HEIGHT};
namespace python = boost::python;
PyObject* arr = PyArray_SimpleNewFromData(2, dims, NPY_FLOAT, &array);
python::handle<> handle(arr);
return python::object(handle);
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("build_day", &build_day, python::args("year", "day"));
}
Interactive Wykorzystanie:
>>> import example
>>> day = example.build_day(1, 2);
>>> assert(day)
Należy pamiętać, że aby stworzyć minimalną kompletny przykład, powyższy przykład ma szydzili PyArray_SimpleNewFromData()
że po prostu zwraca ciąg Pythona. Ważne jest, aby zapoznać się z dokumentacją w celu ustalenia, czy PyObject*
została wypożyczona, czy też nie, oraz czy istnieją jakieś wymagania dotyczące czasu życia między obiektem a jego argumentami. W przypadku PyArray_SimpleNewFromData()
, zwrócony PyObject*
:
- już ilość jego odniesienia zwiększona
- Żywotność pamięci podstawowego dostarczanego do tablicy musi być co najmniej tak długa jak zwróconej
PyObject
. Funkcja build_day()
w pierwotnym pytaniu nie spełnia tego wymogu.