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对象。如果指定f
是Foo
,则可以使用_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)