2012-12-02 100 views
7

我試圖用cython將C++類暴露給python。我將它們的定義寫在* .pxd文件中,並在* .pyx文件中實現了一個包裝器。但是我試圖傳遞給指向擴展類型的函數指針。這裏是簡化的例子。將python對象轉換爲cython指針

foo.pyx

from c_foo cimport cFoo 
cdef class Foo: 
    cdef cFoo* _impl 

c_foo_holder.pxd

cdef extern from "FooHolder.h": 
    cdef cppclass cFooHolder: 
     cFooHolder(cFoo* foo)  

foo_holder.pyx

from c_foo_holder cimport cFooHolder 
from c_foo cimport cFoo 

cdef class FooHolder: 
    cdef cFooHolder* _impl 
    def __init__(self, foo): 
     self._impl = new cFooHolder(<cFoo*>(foo._impl)) # error here  

但是在L ast line得到錯誤「Python對象不能轉換爲基本類型指針」。我也嘗試過其他幾種方法,但是毫無效果:

# error: 'Foo' is not a type identifier 
from foo import Foo 
def __init__(self, Foo foo): 
    self._impl = new cFooHolder(foo._impl) 

# error: 'Foo' is not a type identifier 
def __init__(self, foo): 
    self._impl = new cFooHolder(<Foo>(foo)._impl) 

回答

3

我找到了解決辦法。你必須告訴cython foo._impl確實是cFoo *實例。這可以通過提供Foo定義來實現(例如在foo.pxd中)。之後,您可以將python對象轉換爲Foo,並且cython將知道其_impl字段的類型爲cFoo *。

foo.pxd

from c_foo cimport cFoo 
cdef class Foo: 
    cdef cFoo* _impl 

foo.pyx

from c_foo cimport cFoo 
cdef class Foo: 
    # methods implementation 

c_foo_holder.pxd

cdef extern from "FooHolder.h": 
    cdef cppclass cFooHolder: 
     cFooHolder(cFoo* foo)  

foo_holder.pyx

from c_foo_holder cimport cFooHolder 
from c_foo cimport cFoo 
from foo cimport Foo 

cdef class FooHolder: 
    cdef cFooHolder* _impl 
    def __init__(self, foo): 
     self._impl = new cFooHolder((<Foo?>foo)._impl) 
0

__init__構造函數只能接受純粹的Python對象,也有__cinit__但它只能接受Ç基本類型。

當你傳遞給美孚它__init__不能看到_impl成員,僅蟒蛇類型的成員就可以看出。

的解決辦法是明確地傳遞cFoo*Init()方法,模擬構造函數:

cdef class FooHolder: 
    cdef cFooHolder* _impl 
    cdef void Init(self, cFoo* foo_impl): 
     self._impl = new cFooHolder(foo_impl) 

這樣調用它:

fooHolder = new FooHolder() 
fooHolder.Init(foo._impl) 
+0

看來,我不能做,要麼雖然foo是一個Python對象。我錯過了什麼嗎?如果我用'def'定義函數,我得到'不能將Python對象參數轉換爲'cFoo *'類型,如果我用'cdef'定義它,我不能從python調用它。 – DikobrAz

+1

@DikobrAz嗯似乎你不能調用類外的cdef方法,嘗試通過全局函數而不是'Init()'方法設置類成員,請參閱此示例:http://stackoverflow.com/a/ 12205374/623622 –

+0

沒有運氣。據我所知,我不能從python調用cdef成員,他們只能在cython模塊中訪問。我不能(不知道如何)將python對象轉換爲cython指針,所以這實際上是問題所在。 – DikobrAz

相關問題