![](/img/trans.png)
[英]In Cython class, what's the difference of using __init__ and __cinit__?
[英]How to pass struct pointer to __cinit__ of Cython's cdef class
我正在嘗試使用cinit實現 cdef 類,該類必須使用 cdef 結構指針。
C頭
typedef struct foo *FOO;
PXD 文件:
extern ...:
cdef struct foo
ctypedef foo *FOO
PYX 文件:
cdef class ClassX(object):
def __cinit__(self, FOO arg):
...
Cython 編譯器說“無法將 Python 對象參數轉換為‘FOO’類型”。 有什么問題以及如何將 struct 指針傳遞給cinit ?
看起來我發現了類似的問題: how to cython class function's parameter accept c++ struct 。 簡短回答:不可能將 C-struct 傳遞給 Python (def) 函數。 我必須將結構包裝到 Python 對象中。
以下是我為我的案例設法解決它的一些方法,這些方法非常具體。
方法 1 - 將指針轉換為 uint64 數字(有點臟)您必須確保在復制之前沒有刪除引用,但首先將您的結構指針轉換為一個無符號的 64 位數字,然后轉換並可能 deref 回您的對象. 像這樣
from cython.operator cimport dereference as deref
ctypedef unsigned long long uint64_t
...
cdef class SomeClass(object):
cdef FooStruct foo
def __cinit__(self, uint64_t arg):
self.foo = deref(<FooStruct*> arg) # preferably copy over keeping pointer
然后構造它
cdef FooStruct yourfoo = ... # your struct
cdef SomeClass res
res = SomeClass(<uint64_t> &yourfoo)
這不是最漂亮的解決方案,但它適用於特定情況。
方法 2 - 相同的 PYX 文件分配函數(首選) 這種方法我發現只適用於同一個 PYX 文件中的對象引用。 因此,如果您使用復制數據的 setter 函數定義cdef class
,該函數未暴露給 python,那么您可以更新內部結構。
cdef class SomeClass(object):
cdef FooStruct foo
def __cinit__(self):
...
cdef void _set(self, FooStruct &data):
self.foo = data # copy
現在構造它的兩行
cdef FooStruct yourfoo = ... # your struct
cdef SomeClass res
res = SomeClass()
res._set(yourfoo)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.