【问题标题】:How do I write an extension type that wraps pre-allocated data?如何编写包装预分配数据的扩展类型?
【发布时间】:2013-02-24 10:10:09
【问题描述】:

我有一些来自已经分配和初始化的结构的数据。 我可以保证在这些对象的任何生命周期内都不会释放数据。如何将其包装在 Cython 的 Python 对象中?以下确实工作,但我希望它能解释我的意图:

from libc.stdlib cimport malloc

ctypedef struct Point:
    int x
    int y

cdef class _MyWrapper:
    cdef Point* foo
    def __cinit__(self, Point* foo):
        self.foo = foo

def create_eternal_MyWrapper(int x, int y):
    cdef Point* p
    p = <Point*>malloc(sizeof(Point))
    p.x = x
    p.y = y
    return _MyWrapper(p)

在此运行 cython 的输出:

Error compiling Cython file:
------------------------------------------------------------
...
def create_eternal_MyWrapper(int x, int y):
    cdef Point* p
    p = <Point*>malloc(sizeof(Point))
    p.x = x
    p.y = y
    return _MyWrapper(p)
                      ^
------------------------------------------------------------

examplecy.pyx:17:23: Cannot convert 'Point *' to Python object

【问题讨论】:

  • 什么是MyAllocatedData?一个C结构? cdef class?一种 Python 对象?
  • A C 类型。具体来说,一个结构。您想要 C 和 Cython 中的确切结构定义吗?
  • 我认为这些细节并不重要。但是如何它“不起作用”?你能提供一个better 的例子吗?
  • @delnan 很公平,对不起。我现在已经举了一个完整的例子。
  • 问题不在于您分配数据的方式,而在于您将指针传递给构造函数的方式。传递 NULL 指针会导致同样的错误

标签: python c cython


【解决方案1】:

正如here 所讨论的,__init____cinit__ 方法都使用PyObject_Call API 函数,该函数只能接受 PyObject 类型的参数。因此,正如FAQ 中所建议的那样,您应该在全局工厂方法中初始化 C 属性:

from libc.stdlib cimport malloc

ctypedef struct Point:
    int x
    int y

cdef class _MyWrapper:
    cdef Point* fooless
    def __init__(self, *args, **kwargs):
        raise TypeError("This class cannot be instantiated from Python")

cpdef _MyWrapper create_MyWrapper(int x, int y):
    cdef _MyWrapper w = _MyWrapper.__new__(_MyWrapper)

    cdef Point* p
    p = <Point*>malloc(sizeof(Point))
    p.x = x
    p.y = y

    w.foo = p

    # initialize all other fields explicitly
    # ...

    return w

当然可以在_MyWrapper 本身中创建一个专用的初始化方法,但我认为这会相当不安全,因为用户可能会在类实例化后忘记调用此类方法。

PS:很高兴看看是否存在更简单的解决方案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-05
    • 2019-12-05
    • 1970-01-01
    • 2015-11-05
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    相关资源
    最近更新 更多