如何在Cython中从另一个包装对象返回包装的c++对象
How do I return wrapped C++ Objects in Cython from another wrapped Object?
我一直在用Cython包装c++类。现在我有以下问题:类A有一个方法foo(),它返回类b的实例。两者都是c++类。两者都在Cython中包装为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对象,并返回它?
从您的问题中不完全清楚foo
是否通过指针或值返回(即是否具有签名B* foo()
或B foo()
)。你需要做什么取决于这个——我已经展示了两者。
我认为你遇到的问题是,PyB
的__init__
或__cinit__
方法只能接受Python对象作为参数,所以你没有办法传递c++ B
对象。解决方案是创建一个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
holder (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
holder (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*
。
如果可以的话,你最好使用move构造函数而不是copy构造函数,但是你不需要告诉Cython这两种构造函数(c++会自动选择正确的构造函数)。
- 包装一个对象并假装它是一个 int
- 错误:"释放后使用包装器对象 (WRAPPER_ESCAPE)"
- C++包装库:在堆栈上分配C++ C 中的对象
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 在 C++ 对象包装器中安全地包含 C 代码
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 如何将包装类的对象用作包装函数中的参数
- 如何包装对象,使它们成为无法交互的单独类型?
- 由 pybind11 包装的对象的内存开销
- 将抽象值对象保存在包装器中和继承的用法中
- 将numpy对象传递到Pythonqt包装器
- 如何将 Python 中的字节对象传递给用 Swig 包装的C++函数
- 将 C 对象的数组包装到类C++
- 泛型对象包装器
- OpenGL对象包装器中的自动绑定
- 如何编写安全的原子对象包装器?
- 我的GLSL着色器对象/包装器是否应该封装加载/设置VertexArrayObject
- 将C++对象包装在外部“C”中
- 移动值/对象包装器的构造函数