python转cython_python – 使用现有C对象初始化Cython对象

C模型

假设我有以下C数据结构,我希望向Python公开.

#include

#include

struct mystruct

{

int a, b, c, d, e, f, g, h, i, j, k, l, m;

};

typedef std::vector> mystruct_list;

提升Python

我可以使用boost :: python使用以下代码相当有效地包装它们,轻松地允许我使用现有的mystruct(复制shared_ptr)而不是重新创建现有对象.

#include "mystruct.h"

#include

using namespace boost::python;

BOOST_PYTHON_MODULE(example)

{

class_>("MyStruct", init<>())

.def_readwrite("a", &mystruct::a);

// add the rest of the member variables

class_("MyStructList", init<>())

.def("at", &mystruct_list::at, return_value_policy());

// add the rest of the member functions

}

用Cython

在Cython中,我不知道如何从mystruct_list中提取项目,而不复制底层数据.我不知道如何从现有的shared_ptr< mystruct>初始化MyStruct,而不是以各种形式之一复制所有数据.

from libcpp.memory cimport shared_ptr

from cython.operator cimport dereference

cdef extern from "mystruct.h" nogil:

cdef cppclass mystruct:

int a, b, c, d, e, f, g, h, i, j, k, l, m

ctypedef vector[v] mystruct_list

cdef class MyStruct:

cdef shared_ptr[mystruct] ptr

def __cinit__(MyStruct self):

self.ptr.reset(new mystruct)

property a:

def __get__(MyStruct self):

return dereference(self.ptr).a

def __set__(MyStruct self, int value):

dereference(self.ptr).a = value

cdef class MyStructList:

cdef mystruct_list c

cdef mystruct_list.iterator it

def __cinit__(MyStructList self):

pass

def __getitem__(MyStructList self, int index):

# How do return MyStruct without copying the underlying `mystruct`

pass

我看到许多可能的解决方法,但没有一个是非常令人满意的:

我可以初始化一个空的MyStruct,并在Cython中通过shared_ptr进行分配.然而,这将导致浪费一个初始化的结构,绝对没有理由.

MyStruct value

value.ptr = self.c.at(index)

return value

我也可以将现有mystruct中的数据复制到新的mystruct中.然而,这遭受类似的膨胀.

MyStruct value

dereference(value.ptr).a = dereference(self.c.at(index)).a

return value

我还可以为每个__cinit__方法公开一个init = True标志,如果C对象已经存在(当init为False时),它将阻止在内部重建对象.但是,这可能会导致灾难性问题,因为它会暴露给Python API并允许取消引用null或未初始化的指针.

def __cinit__(MyStruct self, bint init=True):

if init:

self.ptr.reset(new mystruct)

我也可以使用暴露于Python的构造函数(它将重置self.ptr)重载__init__,但如果从Python层使用__new__,这将有危险的内存安全性.

底线

我很想使用Cython,编译速度,语法糖和许多其他原因,而不是相当笨重的boost :: python.我现在正在看pybind11,它可能会解决编译速度问题,但我仍然希望使用Cython.

有没有什么办法可以在Cython中以惯用方式完成这么简单的任务?谢谢.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值