簡體   English   中英

在 Cython 中傳遞指向構造函數的指針

[英]Passing pointer to constructor in Cython

這可能是一個愚蠢的問題,但是如何將“原始”指針傳遞給 Cython 對象的構造函數? 問題似乎是__init____cinit__不能是cdefcpdef但必須是def

這里的最佳實踐解決方法是什么? 為分配的內存創建一個包裝類?

以下作品

# ex1.pyx
from libc.stdlib cimport malloc, free

cdef class Klass1:
    cdef void * ptr

    cdef void _init(self, void * ptr):
        self.ptr = ptr

    def bar(self):
        free(self.ptr)

def foo():
    o = Klass1()
    o._init(malloc(100))
    o.bar()

雖然以下沒有:

# ex2.pyx
from libc.stdlib cimport malloc, free

cdef class Klass2:
    cdef void * ptr

    def __init__(self, ptr):  # __init__ cannot be cdef
        self.ptr = ptr

    def bar(self):
        free(self.ptr)

def foo():
    o = Klass2(malloc(100))
    o.bar()

以下setup.py可用於構建:

from distutils.core import setup
from Cython.Build import cythonize

setup(name='ex1', ext_modules=cythonize('ex1.pyx')) # or ex2.pyx

有多種選擇,具體取決於用例。 __init__ / __cinit__旨在從 Python 構建您的類(指針無意義)因此受到限制。

在您的示例中(我懷疑是簡化的),您可以將malloc調用放在構造函數中:

# rest of class definition goes here
def __init__(self,size):
  self.ptr = malloc(size)
# and more code follows

另一種可能性是使用靜態方法而不是__init__ (這實際上是在 Cython 文檔中為此目的而建議的: http ://docs.cython.org/src/userguide/extension_types.html#c-methods)。 我剛剛從文檔中復制了示例:

cdef class OwnedPointer:
    cdef void* ptr

    cdef __dealloc__(self):
        if ptr != NULL:
            free(ptr)

    @staticmethod
    cdef create(void* ptr):
        p = OwnedPointer()
        p.ptr = ptr
        return ptr

第三種選擇是按照您的建議使用包裝類 - 問題在於您仍然必須以某種方式構造它們(因此您又回到了提到的兩種技術)。 當指針實際上指向已知的 C/C++ 數據類型時,這可能是最合適的,您可以從另一個函數中獲取或自己輕松構造,並且能夠從純 Python 代碼處理這些數據類型會很有用。 一個很好的大綱在http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#create-cython-wrapper-class - 根據你想做的事情,你可能只選擇創建一個構造函數和析構函數而不是映射成員函數(如果有的話)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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