假設我試圖包裝vector
。從Cython模塊中導出包裝的C++類
module/__init__.pxd:
from libcpp.vector cimport vector
from libc.stdint cimport uint32_t
cdef class MyVector:
cdef vector[uint32_t]* thisptr
module/__init__.pyx:
from libc.stdint cimport uint32_t
from libcpp.vector cimport vector
from cython.operator cimport dereference as deref
cdef class MyVector:
# the field declaration is in *.pxd
def __cinit__(self):
self.thisptr = new vector[uint32_t]()
self.thisptr.push_back(42)
def __dealloc__(self):
del self.thisptr
self.thisptr = <vector[uint32_t]*> NULL
def mysize(self):
return self.thisptr.size()
def myget(self):
return deref(self.thisptr)[0]
module/__init__.pyxbld
和run.pyxbld:
def make_ext(modname, pyxfilename):
from distutils.extension import Extension
return Extension(
name=modname,
sources=[pyxfilename],
language='c++'
)
run.pyx:
from module cimport MyVector
cdef main():
obj = MyVector()
print(obj.thisptr.size()) # 1
print(obj.mysize()) # 1
print(obj.myget()) # 42
main()
test.py:
import pyximport
pyximport.install()
import run
當我運行test.py
,它具有以下回溯崩潰:
Traceback (most recent call last):
File "/usr/lib64/python3.4/site-packages/pyximport/pyximport.py", line 210, in load_module
mod = imp.load_dynamic(name, so_path)
File "module/__init__.pxd", line 5, in init run (/home/pastafarianist/.pyxbld/temp.linux-x86_64-3.4/pyrex/run.cpp:918)
cdef class MyVector:
AttributeError: 'module' object has no attribute 'MyVector'
如果我搬到module/__init__.pyx
到module.pyx
和module/__init__.pxd
至module.pxd
相同的代碼工作。我錯過了什麼,如何修復它?
其他一些相關問題。
- 有沒有什麼辦法,露出一個模板包裝到用Cython代碼,這樣我可以有
MyVector[uint16_t]
無需再寫包裝? - 我正確地爲每個與C++代碼交互的源文件添加一個
pyxbld
文件嗎?這是多餘的嗎? (我喜歡pyximport
的便利,我不想每次都手動重新編譯代碼,而我仍然試圖讓它起作用。) - 如何將
module
編譯爲獨立擴展?setup.py
應該是什麼樣子? - 在上面的代碼中,我在調用C++方法之前從未使用過
deref
。 Cython如何理解我的意思是->
,我的意思是.
?
我希望能夠幫到你解決這些問題。
UPD:其實,我是包裝紙谷歌的sparsehash
,我已經想通了way to do what I wanted,但它看起來像黑魔法。我仍然希望澄清一下這個錯誤是怎麼回事,以及如何正確編寫Cython包裝器。
謝謝。我想說明的是,我想要一個更接近pythonic接口的包裝類,即使在Cython模塊中也是如此。你能提供一個簡單的Cython包裝的例子嗎?我已經在GSL之後的UPD中引用了我引用的解決方案(這也是我對「__init __。py」的解釋),但它太複雜了,而且我可能會過度設計一些東西。 – Pastafarianist
它看起來不錯 - 你已經使它像一個'dict'一樣工作,我認爲它就像你可以得到的Pythonic一樣。不幸的是,Cython確實包含了獨立包裝每一個功能,這給你很長的界面,所以下一次我會說,把它切成你需要的位。我看不到其他很多東西。 – DavidW