繁体   English   中英

如何使用Cython围绕C Struct编写完整的Python包装器?

[英]How to write a complete Python wrapper around a C Struct using Cython?

我正在使用Cython为Python的C库编写一个高级接口。
我有一个扩展Type 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() __cinit__导致: 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 ,因此它可以愉快地调用与A关联的cdef函数。 如果传递的不是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__函数指定相关输入的类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM