typedef int bar;
typedef struct _foo
{
bar* b;
} foo;
extern foo* foo_new();
extern bar* foo_bar_new(foo* f);
cdef extern from "foo.h":
ctypedef int bar;
ctypedef struct foo:
bar* b
foo* foo_new();
bar* foo_bar_new(foo* f);
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
在标记的行处抛出错误。
我不太确定我做错了什么。将_ptr
中的Foo
更改为cpdef
会导致相同的错误。
==更新== 我将 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__()
。关于如何解决这个问题的任何想法?
答案 0 :(得分:1)
您需要确保在编译时知道BasePoint
的类型:
f
没有这样做,它必须假设def __cinit__(self, Foo f):
self._ptr = foo_bar_new(f._ptr) # error
是标准的Python属性查找(在运行时完成),因此将是一个标准的Python对象。如果您指定_ptr
是f
,那么它就可以使用Foo
的已知定义。
答案 1 :(得分:0)
我一直在使用似乎正常工作的工厂功能模型的修改。
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)