难以从另一个对象访问结构指针



foo.h

typedef int bar;
typedef struct _foo
{
    bar* b;
} foo;
extern foo* foo_new();
extern bar* foo_bar_new(foo* f);

foo.pxd

cdef extern from "foo.h":
    ctypedef int bar;
    ctypedef struct foo:
        bar* b
    foo* foo_new();
    bar* foo_bar_new(foo* f);

foo.pyx

from foo cimport *
cdef class Foo:
    cdef foo* _ptr
    def __cinit__(self):
        self._ptr = foo_new()
cdef class Bar:
    cdef bar* _ptr
    def __cinit__(self, f):
        self._ptr = foo_bar_new(f._ptr)   # error
                                ^
foo.pyx:11:33: Cannot convert Python object to 'foo *'

cython foo.pyx在标记的线上丢下错误。

我不太确定我在做什么错。将Foo中的_ptr更改为cpdef会导致相同的错误。

== update ==我将 foo.pyx 更改为以下内容。

from foo cimport *
cdef class Foo:
    cdef foo* _ptr
    def __cinit__(self):
        self._ptr = foo_new()
    def new_bar(self):
        cdef bar* b
        b = foo_bar_new(self._ptr)
        tmp = Bar()
        tmp._set(b)
        return tmp
cdef class Bar:
    cdef bar* _ptr
    cdef _set(self, bar* bptr):
        self._ptr = bptr
    def get(self):
        return bar_get(self._ptr)

我可以做f=Foo(); b=f.new_bar(),但这对我来说似乎并不理想,因为我不能使用Bar(f)或类似的创建。问题是我不能cdef __cinit__(),因为这是一种特殊的方法。也不能cdef __init__()。关于如何解决此问题的任何想法?

您需要确保它知道哪种类型f是在编译时:

def __cinit__(self, Foo f):
    self._ptr = foo_bar_new(f._ptr)   # error

如果不这样做,就必须假设_ptr是标准的Python属性查找(在运行时完成),因此将是标准的Python对象。如果指定fFoo,则可以使用_ptr的已知定义。

我一直在使用似乎可以正常工作的工厂功能模型的修改。

cdef class Bar:
    cdef bar* _ptr
    def __cinit__(self):
        self._ptr = NULL
    cdef from_ptr(self, bar* ptr):
        self._ptr = ptr
        return self
cdef class Foo:
    cdef foo* _ptr
    def new_bar(self):
        cdef bar* b
        b = foo_bar_new(self._ptr)
        return Bar().from_ptr(b)

最新更新