gpt4 book ai didi

python - 如何使用 Cython 围绕 C 结构编写完整的 Python 包装器?

转载 作者:太空狗 更新时间:2023-10-29 18:34:03 24 4
gpt4 key购买 nike

我正在使用 Cython 为 Python 的 C 库编写高级接口(interface)。
我有一个扩展类型 A,它使用指向更复杂的 C 上下文结构 c_context 的指针来初始化库。指针保存在A中。
A 也有一个 def 函数,它又创建了另一个扩展类型 B,用库函数调用初始化另一个 C 结构。 B 中的后续库调用需要此结构。
B 需要来自 Ac_context 指针,它被我包装在扩展类型 py_context 中以便传递它从 B__cinit__:

#lib.pxd (C library definitions)
cdef extern from "lib.h":
ctypedef struct c_context:
pass

#file py_context.pxd
from lib cimport c_context

cdef class py_context:
cdef c_context *context
cdef create(cls, c_context *context)
cdef c_context* get(self)

#file py_context.pyx
def class py_context:
@staticmethod
cdef create(cls, c_context *c):
cls = py_nfc_context()
cls.context = c
return cls

cdef c_context* get(self):
return self.context

传递具有正确 C 上下文的包装器可以完美地工作。

现在我需要再次从 py_context 中获取 C 结构并将其保存在 B 中。我将 cdef c_context get(self) 添加到 py_context.pxd/pyx。从 Bs __cinit__ 调用 py_context.get() 导致:AttributeError: py_context object has no attribute get.

在 Cython 中调用 cdef 函数时,我似乎没有头绪。

所以我的问题是:再次从我的包装类中提取 C 结构的最佳方法是什么?

最佳答案

问题在于 Cython 在编译时不知道 py_context 变量的数据类型。对 cdef 函数的调用在编译时解析,并且不存在在运行时通过属性查找(与普通 Python 函数一样)找出它的机制。

[请注意,在 Cython 中编写的 def 函数仍然是经过编译的,并且可以指定数据类型,因此如果它们具有正确的信息,则完全能够调用 cdef 函数。]

您没有给出出错的相关代码(B 类型的构造函数),但这是一个非常简化的示例,希望它能为您提供几种修复方法:

cdef class A:
cdef f(self):
return

def f1(var):
var.f()

#f1(A()) # will fail at runtime with an attribute error

f1 中,var 的类型是未知的,因此您不能调用 cdef 函数。

def f2(A var):
var.f()

f2(A()) # will work
f2(1) # will fail, int can't be converted to A

f2中,var的类型被限制为A,因此它可以愉快地调用cdefA 关联的函数。如果您将不是 A 的内容传递给它,您将在运行时得到一个 TypeError

def f3(var):
cdef A another_reference_to_var = var # this does test that the types match
another_reference_to_var.f()

f3(A()) # will work
f3(1) # will fail, int can't be converted to A

f3 函数可以接受任何类型的变量。但是,当您将它分配给 another_reference_to_var 时,它被 cdef 编辑为 A,它会检查类型是否匹配(并在以下情况下引发运行时异常它没有)。由于 another_reference_to_var 在编译时已知为 A,因此您可以调用 Acdef 函数。

本质上,您需要为您的 __cinit__ 函数指定相关输入的类型。

关于python - 如何使用 Cython 围绕 C 结构编写完整的 Python 包装器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37984481/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com