Reputation: 107
I am having a hard time with my first cython program, so please don't discourage me if I have a stupid question.
This is my example:
c_foo.h:
// c_foo.h
class foo:
{
public:
....
std::unique_ptr<2DVector> get_cFoo_unique_ptr(); // Vec2D<T> is a vector of vectors of T
// std::vector<std::vector<T>>
private:
std::unique_ptr<Vec2D> cFoo_unique_ptr; // Vec2D<T> is a vector of vectors of T
}
foo.pyx: # foo.pyx import cython ... # other import from cython.operator cimport unique_ptr as cpp_unique_ptr
cdef extern from c_foo.h:
cdef cppclass c_foo:
...
cpp_unique_ptr get_cFoo_unique_ptr()
cdef class py_foo:
cdef c_foo* cFoo
...
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
So, what I am trying to do here is getting data from C++ unique_ptr and return them in python. And cython complains about it.
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
----------------------------------------------------------
foo.pyx:xx:xx: Cannot convert 'T *' to Python object
Another attempt is that I try other way to declare cython unique_ptr of vectors:
# foo.pyx
import cython
... # other import
from cython.memory cimport unique_ptr as cpp_unique_ptr
from cython.vector cimport vector as cpp_vector
cdef extern from c_foo.h:
cdef cppclass c_foo:
...
cpp_unique_ptr[cpp_vector[cpp_vector[T]]] get_cFoo_unique_ptr()
cdef class py_foo:
cdef c_foo* cFoo
...
def get_Vec2D(self):
return self.cFoo.get_cFoo_unique_ptr().get()
And still the same error:
Cannot convert 'vector[vector[T]] *' to Python object
So, my question is how can I access the data of C++ unique_ptr in cython? And is there any good practice that I should know for passing data between C++ and python via cython?
Thanks
Upvotes: 2
Views: 2095
Reputation: 11009
This kind of thing confused me for a long time. I have only used Cython in a C environment, not C++, so I don't know about other options that might exist in your case. But I'll explain how I do it, and hope that will be helpful.
You must create Python objects at the end of your Cython function, since those are the only valid return values. That means, among other things, that you can't return a pointer or a C array. For example, suppose I have a Cython function f that calculates a double array:
def f():
cdef double aa[1000]
cdef int i
# ....
# some calculation that populates aa
# ....
# Now I can't just return aa because aa isn't a Python object.
# I have to convert it to a Python list:
a = []
for i in range(1000):
a.append(aa[i]) # Cython knows how convert one C float to one Python float
return a
Upvotes: 1