2017-06-10 53 views
0

我的第一個cython程序很困難,所以如果我有一個愚蠢的問題,請不要阻止我。在cython中將C++對象轉換爲python對象?

這是我的例子:

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 進口用Cython ...#等進口 從cython.operator cimport的unique_ptr作爲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() 

所以,我想要的東西o這裏做的是從C++ unique_ptr獲取數據,並在python中返回它們。 和cython抱怨。

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

另一種嘗試,我嘗試其他方法來聲明向量用Cython的unique_ptr:

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

還是一樣的錯誤:

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

所以,我的問題是如何能我在cython中訪問C++ unique_ptr的數據? 有沒有什麼好的做法,我應該知道通過cython在C++和python之間傳遞數據?

感謝

+1

第二個選項接近於正確。如果Cython不知道「T」是什麼,它應該如何將其轉換爲Python對象? – DavidW

+0

請參閱此問題(相似的問題)(https://stackoverflow.com/questions/44686590/initializing-cython-objects-with-existing-c-objects/45038660#45038660)。 TL; DR - 您需要一個工廠類來將C++類轉換爲Python對象以便返回。 Cython會爲內置類型自動執行此操作,但不能用於自定義結構或類。 – danny

回答

1

這種事情弄得我很長一段時間。我只在C環境中使用過Cython,而不是C++,所以我不知道在你的情況下可能存在的其他選項。但我會解釋我是如何做到的,並希望這會有所幫助。

您必須在Cython函數的末尾創建Python對象,因爲這些是唯一有效的返回值。這意味着,除其他外,您不能返回指針或C數組。例如,假設我有一個計算雙數組的Cython函數f:

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