C ++ Model
Let's say I have the following C ++ data structures that I want to open Python.
#include <memory>
#include <vector>
struct mystruct
{
int a, b, c, d, e, f, g, h, i, j, k, l, m;
};
typedef std::vector<std::shared_ptr<mystruct>> mystruct_list;
Boost Python
I can quite efficiently wrap them with boost :: python with the following code, easily allowing me to use the existing mystruct (copying shared_ptr) rather than recreate the existing object.
#include "mystruct.h"
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(example)
{
class_<mystruct, std::shared_ptr<mystruct>>("MyStruct", init<>())
.def_readwrite("a", &mystruct::a);
class_<mystruct_list>("MyStructList", init<>())
.def("at", &mystruct_list::at, return_value_policy<copy_const_reference>());
}
Cython
In Cython, I have no idea how to extract an element from mystruct_list without copying the main data. I do not know how to initialize MyStructfrom an existing shared_ptr<mystruct>one without copying all the data in one of various forms.
from libcpp.memory cimport shared_ptr
from cython.operator cimport dereference
cdef extern from "mystruct.h" nogil:
cdef cppclass mystruct:
int a, b, c, d, e, f, g, h, i, j, k, l, m
ctypedef vector[v] mystruct_list
cdef class MyStruct:
cdef shared_ptr[mystruct] ptr
def __cinit__(MyStruct self):
self.ptr.reset(new mystruct)
property a:
def __get__(MyStruct self):
return dereference(self.ptr).a
def __set__(MyStruct self, int value):
dereference(self.ptr).a = value
cdef class MyStructList:
cdef mystruct_list c
cdef mystruct_list.iterator it
def __cinit__(MyStructList self):
pass
def __getitem__(MyStructList self, int index):
pass
I see many possible workarounds, and none of them are very satisfactory:
MyStruct, Cython shared_ptr. , - .
MyStruct value
value.ptr = self.c.at(index)
return value
MyStruct MyStruct. .
MyStruct value
dereference(value.ptr).a = dereference(self.c.at(index)).a
return value
init=True __cinit__, , C- ( init False). , API Python .
def __cinit__(MyStruct self, bint init=True):
if init:
self.ptr.reset(new mystruct)
__init__ , Python ( reset self.ptr), , __new__ Python.
Bottom-Line
Cython, , , boost:: python. pybind11 , , Cython.
, Cython? .