簡體   English   中英

如何將結構指針傳遞給 Cython 的 cdef 類的 __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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM