Cython-将数组的指针转换为Python对象 [英] Cython - converting pointers to arrays into Python objects

查看:140
本文介绍了Cython-将数组的指针转换为Python对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我已经很接近完成了,可以品尝到。在过去的大约一周时间里,我一直在尝试创建Python扩展程序来与通过Cython用C ++编写的库进行接口。在这里的家伙和几个朋友的帮助下,我设法达到了98%的感觉。剩下的就是这个:我一生都无法弄清楚如何将一个指向无符号短裤数组的指针变成一个python对象(最好是一个列表)。

Alright, I am so close to finishing this I can taste it. Over the past few week or so, I've been attempting to create a Python extension to interface with a library written in C++ via Cython. With a little help from the guys here and a couple of friends, I have managed to get what feels like 98% of the way there. Only thing remaining is this: I can't for the life of me figure out how to turn a pointer to an array of unsigned shorts into a python object (Preferably a list).

有一点背景,我正在尝试与设置回调函数的库的一部分接口,我已经成功地完成了此操作:

A little background, I am trying to interface with a part of the library that sets a callback function, which I have successfully done with this:

global callbackfunc

ctypedef unsigned short const_ushort "const uint16_t"

ctypedef void (*Function1)(const_ushort *data, unsigned width, unsigned height)

cdef extern from "lib.hpp":
    void SetCallback(Function1)

cdef void cSetCallback(Function1 function):
    SetCallback(function)

cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
    global callbackfunc
    callbackfunc(data,width,height)

cSetCallback(callcallback)

def PySetCallback(callbackFunc):
    global callbackfunc
    callbackfunc = callbackFunc

问题发生在函数 callcallback中,出现错误:无法转换'const_ushort *'到Python对象。我对此的第一个尝试是创建一个新的python列表,然后循环遍历以将数组的每个元素放入python列表中,如下所示:

The problem occurs within the function "callcallback", where I get the error: "Cannot convert 'const_ushort *' to Python object". My first attempt around this was to create a new python list, and loop through to get each element of the array into a python list, like this:

datalist = []
for i in range(width*height):
    datalist += data[i]

不幸的是,这让我用编译后的cython代码使我难以将类型定义为 const const unsigned short,这显然是一个问题。

Which, sadly, nets me with the compiled cython code trying to define a type as a "const const unsigned short", which is obviously a problem.

然后我尝试了此操作:

datalist = []
for i in data:
    datalist += i

这给了我 C数组迭代需要已知的结束索引 。请注意,我对C / C ++的了解很少,所以对我来说这大部分意义不大。

Which gives me "C array iteration requires known end index". Note that I know very little C/C++, so most of this doesn't make much sense to me.

因此,无论如何,有没有有效的方法来翻译像这样将指针指向python对象(最好比遍历数组更快,因为它通常大约有57344个项目,而且这对时间很敏感)

So, anyways, is there any effective way of translating a pointer like that into a python object (Preferably faster than looping through the array, since it's usually about 57344 items, and this is quite time sensitive)

Edit
就像我提到的那样,需要更多说明,我正在使用回调,并且库中的C ++函数调用该函数将指针指向 const uint_16数组,这就是为什么我以这种方式定义了const_ushort,因为否则类型将无法统一。我无法以任何方式修改该库。

Edit: A little more clarification, as I mentioned, I'm working with callbacks, and the C++ function within the library that calls this sends a pointer to an array of "const uint_16"s, which is why I defined const_ushort that way, because otherwise the types don't unify. I cannot modify the library in any way.

Edit2
看起来像我理解的那样。我最终要做的是将数组显式转换为无符号短裤的数组,而不是const无符号短裤的数组,我可以用非常量索引它们。为此,我创建了另一个这样的C ++函数(其他人为我编写了它,我几乎不了解C ++):

Edit2: Looks like I got it. What I ended up having to do was explicitly cast the array as an array of unsigned shorts rather than an array of const unsigned shorts to I could index them with a non constant. To achieve this, I created another C++ function like this (Someone else wrote it for me, I barely know C++):

unsigned short *convert_short(const unsigned short *test){ return const_cast<unsigned short *>(test); }

这使我可以在自己的计算机上创建 getindex 功能并根据函数返回正确的值。是的,Python似乎正确地读取了数组,没什么,所以这种情况似乎已经结束。

and that allowed me to create the "getindex" function within my class and return the correct values based on the function. So yeah, Python seems to be reading the arrays correctly and whatnot, so this case seems closed. Thanks a lot.

推荐答案

ctypedef unsigned short const_ushort "const uint16_t"

使 const 出现在C代码中,因此您得到 typedef unsigned short const uint16_t ,其中 const 是没有意义的。 (它也重新定义了标准类型 uint16_t ,它不应这样做。)

makes the const appear in the C code, so you get typedef unsigned short const uint16_t in which the const is meaningless. (It also redefines the standard type uint16_t, which it shouldn't.)

使用以下方法可能会获得更大的成功

You may have more success with

ctypedef unsigned short *ushort_p "ushort_p"

由于某些原因,Cython似乎无法识别C const 关键字。您可能需要对回调使用包装器来处理 const 问题。

For some reason, Cython seems not to recognize the C const keyword. You may have to use a wrapper around your callbacks to deal with the const issue.

如果要使用指针转换为Python对象,然后将其包装在 cdef类中。确保这些类记录了高度和宽度,因为这些高度和宽度没有记录在C数组中。

If you want the pointer translated into a Python object, wrap it in a cdef class. Make sure the class records the height and width, since these are not recorded with the C array.

这篇关于Cython-将数组的指针转换为Python对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆