2017-06-10 1 views
0

J'ai de la difficulté avec mon premier programme Cython, alors ne me découragez pas si j'ai une question stupide.Conversion d'un objet C++ en objet python dans Cython?

Ceci est mon exemple:

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 importation cython ... # autre importation de cython.operator CIMPORT unique_ptr comme 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() 

Alors, ce que je veux t o Ici, vous obtenez des données de C++ unique_ptr et les renvoyez dans python. Et Cython se plaint à ce sujet.

def get_Vec2D(self): 
    return self.cFoo.get_cFoo_unique_ptr().get() 
---------------------------------------------------------- 
foo.pyx:xx:xx: Cannot convert 'T *' to Python object 

Une autre tentative est que je tente autre façon de déclarer cython unique_ptr des vecteurs:

# 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() 

Et toujours la même erreur:

Cannot convert 'vector[vector[T]] *' to Python object 

Alors, ma question est de savoir comment J'accède aux données de C++ unique_ptr dans Cython? Et y a-t-il de bonnes pratiques que je devrais connaître pour transmettre des données entre C++ et python via Cython?

Merci

+1

La deuxième option est proche de la droite. Comment Cython est-il supposé le convertir en un objet Python s'il ne sait pas ce qu'est 'T'? – DavidW

+0

Voir cette [question pour une réponse similaire] (https://stackoverflow.com/questions/44686590/initializing-cython-objects-with-existing-c-objects/45038660#45038660). TL; DR - vous avez besoin d'une classe factory pour convertir la classe C++ en un objet Python pour qu'elle soit retournée. Cython le fait automatiquement pour les types intégrés mais ne peut pas le faire pour des structures ou des classes personnalisées. – danny

Répondre

1

Ce genre de choses me confondre depuis longtemps. J'ai seulement utilisé Cython dans un environnement C, pas C++, donc je ne sais pas d'autres options qui pourraient exister dans votre cas. Mais je vais vous expliquer comment je le fais, et j'espère que cela sera utile.

Vous devez créer des objets Python à la fin de votre fonction Cython, car ce sont les seules valeurs de retour valides. Cela signifie, entre autres, que vous ne pouvez pas renvoyer un pointeur ou un tableau C. Par exemple, supposons que j'ai une fonction Cython f qui calcule un double tableau:

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