您的问题并不完全清楚 foo 是通过指针还是值返回(即它是否具有签名 B* foo() 或 B foo())。你必须做什么取决于这一点 - 我已经展示了两者。
我认为您遇到的问题是PyB 的__init__ 或__cinit__ 方法只能将Python 对象作为参数,因此您无法通过C++ @987654327 @object in。解决方法是创建一个PyB,它要么是空的,要么具有默认的C++ 对象为ptr,然后替换它。
C++ 代码的包装看起来像这样
cdef extern from "somefile.hpp":
cdef cppclass A:
B foo1()
B* foo2()
cdef cppclass B:
# only need to provide these for foo1_alternative
B()
B(const B&)
请注意,我提供了两个版本的foo - foo1 按值返回,foo2 返回指针。
Python B 持有者 (PyB) 看起来像
cdef class PyB:
cdef B* ptr
def __cinit__(self,make_ptr=True):
if make_ptr:
self.ptr = new B()
else:
self.ptr = NULL
def __dealloc__(self):
del self.ptr
我提供了一个可选的 make_ptr 参数,您可以将其设置为 False 以避免将 self.ptr 设置为任何值。
然后是 Python A 持有者 (PyA)
cdef class PyA:
cdef A* ptr
# code goes here
def foo1(self):
cdef PyB val = PyB()
val.ptr[0] = self.ptr.foo1() # use move (or copy) assignment operator
def foo1_alternative(self):
cdef PyB val = PyB(make_ptr=False)
val.ptr = new B(self.ptr.foo1()) # use move (or copy) constructor
def foo2(self):
cdef PyB val = PyB(make_ptr=False)
val.ptr = self.ptr.foo2()
对于返回指针的foo2,您只需创建一个空的PyB 并将Foo* 赋值给self.ptr。对于foo1,您有两个选择,其中之一是创建一个PyB,然后使用移动(或复制)赋值运算符复制数据。第二个选项涉及创建一个空的PyB,然后使用Bs 移动(或复制)构造函数来创建一个B*。
如果可以的话,你最好使用移动构造函数而不是复制构造函数,但是你不需要告诉 Cython 任何一个(C++ 会自动选择正确的)。