我用Cython包装了C ++ Classes。现在我有以下问题:类A有一个方法foo(),它返回一个B类实例。两个都是C ++类。两者都用Cython包装到Class PyA和PyB。我想以某种方式使用户可以访问方法foo(),用户调用PyA_object.foo()并获取PyB_object。我该如何实现该方法?
cimport cppClassA
cdef class A:
cdef cppClassA.A *ptr
...
def foo():
return self.ptr.foo()
这样我返回直接C ++类B,但我想返回一个PyB。因此我需要创建一个PyB对象,但是如何构造PyB的 cinit ()方法呢?如何将self.ptr.foo()中返回的对象提供给新的PyB对象并返回呢?
答案 0 :(得分:0)
根据您的问题,foo
是否通过指针或值返回(即它是否具有签名B* foo()
或B foo()
)并不完全清楚。你要做的事情取决于这一点 - 我已经证明了这两点。
我认为您遇到的问题是__init__
或__cinit__
PyB
方法只能将Python对象作为参数,因此您可以使用#{1}}或B
方法作为参数。我无法传递C ++ PyB
对象。解决方案是创建一个空的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&)
,然后替换它。
C ++代码的包装看起来像这样
foo
请注意,我提供了两个版本的foo1
- foo2
,它们按值返回,B
返回指针。
Python 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
,以避免将A
设置为任何内容。
Python 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
来复制数据。第二个选项涉及创建一个空的B
,然后使用B*
的移动(或复制)构造函数来创建form1.Action = "myURL";
。
如果可以的话,你最好使用移动构造函数而不是复制构造函数,但是你不需要告诉Cython(C ++会自动选择正确的)。