【发布时间】:2019-02-12 15:20:23
【问题描述】:
我正在使用 Cython 在 python 中包装一个 c++ 库。不幸的是,我无法访问 c++ 库。因此,我必须找到一种方法来包装 lib API 所公开的结构和函数。
我的问题是关于包装 c++ 结构的最佳方式;随后,如何在 python 中创建内存视图并将其指针(第一个元素地址)传递给 c++ 函数,参数为 cpp 结构数组。
例如,假设我有以下 h 文件:
//test.h
struct cxxTestData
{
int m_id;
double m_value;
};
void processData(cxxTestData* array_of_test_data, int isizeArr)
我的 pyx 文件如下所示
cdef extern from "Test.h":
cdef struct cxxTestData:
int m_id
double m_value
cdef class pyTestData:
cdef cxxTestData cstr
def __init__(self, id, value):
self.cstr.m_id = id
self.cstr.m_value = value
@property
def ID(self):
return self.cstr.m_id
@property
def Value(self):
return self.cstr.m_value
现在,我想创建一些 pyTestData 并将它们存储在一个 dtype 对象数组中。然后我想将此数组作为 cython/python 函数中的内存视图传递。
包装函数将具有以下签名
cpdef void pyProcessData(pyTestData[::1] test_data_arr)
我已经测试了上面的内容,它编译成功。我还设法修改了每个结构的成员。然而,这不是我想要达到的目标。我的问题是如何从这一点开始传递一个数组,其中包含封装在每个 pyTestData 对象中的 c++ 结构(通过 self.cstr)。
作为示例,请查看以下列表:
cpdef void pyProcessData(pyTestData[::1] test_data_arr):
cdef int isize test_data_arr.shape[0]
# here I want to create/insert an array of type cxxTestData to pass it
# to the cpp function
# In other words, I want to create an array of [test_data_arr.cstr]
# I guess I can use cxxTestData[::1] or cxxTestData* via malloc and
# copy each test_data_arr[i].cstr to this new array
cdef cxxTestData* testarray = <cxxTestData*>malloc(isize*sizeof(cxxTestData))
cdef int i
for i in range(isize):
testarray[i] = test_data_arr[i].cstr
processData(&testarray[0], isize)
for i in range(isize):
arrcntrs[i].pystr = testarray[i]
free(testarray)
有人遇到过这种情况吗?有没有更好的方法可以在上述函数中传递我的 python 对象,而不必在内部复制 cxx 结构?
非常感谢,如果我做了根本性的错误,我们深表歉意。
【问题讨论】:
-
1) 我不认为
pyTestData[::1]真的有效——它实际上会毫无怨言地接受objects 的任何数组。我确信它根本没有用于编译,所以编译而不做你想要的感觉就像回归。 2)根本问题是pyTestData是Python对象,所以必须单独分配并且还包含Python引用计数数据。因此,没有可靠的 c++ 对象块供您发送到您的函数(无需复制)。 -
非常感谢您的回答。实际上, pyTestData[::1] 确实可以编译。但是,我同意它接受任何对象数组。因此,不是存储我的对象的最佳选择。我是否必须明确定义 dtype (pyTestDataType = [('m_id', 'int'), ('m_value', 'double')]) 然后将其用于我的签名以便只接受这些对象?你能举个例子吗?这不是真正的问题。但是,它可以帮助我做所有正确的事情。
-
很遗憾,我并没有很好的解决方案...