栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在不复制对象的情况下公开将C ++对象返回给Python的函数?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在不复制对象的情况下公开将C ++对象返回给Python的函数?

如果您拥有现代的C ++编译器并且可以使用右值引用,请移动构造函数和std ::
move,这非常简单。我认为最简单的方法是为向量创建Cython包装器,然后使用move构造函数来掌握向量的内容。

显示的所有代码都在peak_detection_.pyx中。

先包好

std::move
。为了简单起见,我只包装了我们想要的一种情况(
vector<Peak>
),而不是弄乱模板。

cdef extern from "<utility>":    vector[Peak]&& move(vector[Peak]&&) # just define for peak rather than anything else

其次,创建向量包装器类。这定义了像列表一样访问它所必需的Python函数。它还定义了一个函数来调用移动分配运算符

cdef class PyPeakVector:    cdef vector[Peak] vec    cdef move_from(self, vector[Peak]&& move_this):        self.vec = move(move_this)    def __getitem__(self,idx):        return PyPeak2(self,idx)    def __len__(self):        return self.vec.size()

然后定义包装的类

Peak
。这与您的其他类稍有不同,因为它不拥有
Peak
包装的内容(向量包含)。否则,大多数功能保持不变

cdef class PyPeak2:    cdef int idx    cdef PyPeakVector vector # keep this alive, since it owns the peak rather that PyPeak2    def __cinit__(self,PyPeakVector vec,idx):        self.vector = vec        self.idx = idx    cdef Peak* getthisptr(self):        # lookup the pointer each time - it isn't generally safe        # to store pointers incase the vector is resized        return &self.vector.vec[self.idx]    # rest of functions as is    # don't define a destructor since we don't own the Peak

最后实施

getPeaks()

cdef class PyPeakDetection:    # ...        def getPeaks(self, data):        cdef Peak peak        cdef PyPeak new_peak        cdef vector[Peak] peaks = self.thisptr.getPeaks(data)        retval = PyPeakVector()        retval.move_from(move(peaks))        return retval

替代方法:

如果

Peak
是平凡的,你可以去那里你调用一个方法
move
Peak
而上的向量,为您建造
PyPeak
秒。对于这种情况,您在此处移动和复制将等同于`Peak。

如果您不能使用C 11功能,则需要稍微更改一下接口。不用让C

getPeaks
函数返回向量,而是将一个空的向量引用(由拥有
PyPeakVector
)作为输入参数并写入其中。其余的大部分包装都保持不变。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/624523.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号