Cython:can';t将Python对象转换为';双*';
我正在写一个Cython包装到一个C函数。我有一个带有以下签名的pxd文件:Cython:can';t将Python对象转换为';双*';,python,arrays,list,cython,Python,Arrays,List,Cython,我正在写一个Cython包装到一个C函数。我有一个带有以下签名的pxd文件: double contr_hrr(int lena, double xa, double ya, double za, double *anorms) 当我试图从pyx文件调用它时 ... return contr_hrr(len(acoefs),a.origin[0],a.origin[1],a.origin[2],anorms2) 其中anroms2是一个python列表,我得到错误消息: cython/ctw
double contr_hrr(int lena, double xa, double ya, double za, double *anorms)
当我试图从pyx文件调用它时
...
return contr_hrr(len(acoefs),a.origin[0],a.origin[1],a.origin[2],anorms2)
其中anroms2是一个python列表,我得到错误消息:
cython/ctwo.pyx:35:80: Cannot convert Python object to 'double *'
如何将python列表作为双数组传递给C函数?我认为您不能这样做,只能自己转换它:
cimport cython
from libc.stdlib cimport malloc, free
...
cdef double *anorms
cdef unsigned int i;
anorms = <double *>malloc(len(anorms2)*cython.sizeof(double))
if anorms is NULL:
raise MemoryError()
for i in xrange(len(anorms2)):
anorms[i] = anorms2[i]
return contr_hrr(len(acoefs),a.origin[0],a.origin[1],a.origin[2],anorms)
如果你可以切换到C++,你可以直接从<代码>列表[FLASH ] <代码>到<代码>矢量< /代码>:
并直接从Python端调用:anorms2 = [12.0, 0.5, ...]
py_contr_hrr(anorms2, ....)
资料来源:
但是我不知道这是不是一个你可以考虑的选择…当然,这取决于项目的约束条件
编辑:我不知道Nikita的方法(顺便说一句,这是一种优雅的方法),我也不知道哪种方法最适合在大型阵列上的性能
阵列
:
from cpython cimport array
return contr_hrr(.., anorms2_arr.data.as_doubles)
数组
是一个数组。Cython在顶部添加了一些特殊的支持,比如缓冲接口和通过arr.data.as\u xxx
直接访问底层内存块。不幸的是,这种支持只是有文档记录的。
您还可以在中找到有关数组使用的一些详细信息。我最后做的是确保anorms数组在代码的python部分作为数组进行维护,然后按照Nikita的方法使用.data.as_doubles属性将它们动态转换为double。如果我这样做,与在C中以本机方式完成所有工作相比,它的开销似乎非常小
由于种种平凡的原因,我还没有尝试过numpy方法。数组的东西最近有多新?当我尝试cimport array时,我得到了“cython/ctwo.pyx:3:0:'array.pxd'not found”。@Rick我刚刚检查了0.19.1(最后一个)稳定版本,文件就在那里。还使用我的当前版本
0.18
测试了导入:它对我来说运行良好。。。嗯,你的是什么?是加进去的。最新版本通常是最好的。啊!我使用cython 0.16的原因不明。我想我最好升级一下。刚刚尝试通过Macports安装cython,但版本仍然显示为0.16。如果您有机会测试不同的方法,我很想知道哪种方法最快…@Golgauth-我一定会尝试一下。代码的速度是旧方法的2倍,在旧方法中,我使用C直接包装C例程。您的最终方法是什么?也许你可以在上面发表你自己的答案…@Golgauth-Done,见下文。非常感谢你的帖子。我现在正在尝试尼基塔的方法,如果不行,我就试试这个。
from cpython cimport array
cdef array.array anorms2_arr = array.array('d', anorms2)
return contr_hrr(.., anorms2_arr.data.as_doubles)