Python 如何调用Cython';C程序中的带内存视图的cdef函数?

Python 如何调用Cython';C程序中的带内存视图的cdef函数?,python,c,cython,Python,C,Cython,我是Cython的新手,尝试使用cdef函数调用Cython中定义的内存视图函数。我使用的是Mac OSx High Sierra 10.13.1。C代码是用Xcode(V9.1)编写和编译的。pyx文件是使用python3编译的 pvel.pyx cdef public psvel(double [:] lcfarray, double [:] fn,double [:] Q,int axis, int dl, double sR): % few lines of code in p

我是Cython的新手,尝试使用cdef函数调用Cython中定义的内存视图函数。我使用的是Mac OSx High Sierra 10.13.1。C代码是用Xcode(V9.1)编写和编译的。pyx文件是使用python3编译的

pvel.pyx

cdef public psvel(double [:] lcfarray, double [:]  fn,double [:]
   Q,int axis, int dl, double sR):
% few lines of code in python
% not shown here....

main.c

#include <stdio.h>
#include <Python/Python.h>
#include "pvel.h"

int main() {
    Py_Initialize();
    double lc[]={1.2345,2.4343,5.4443,6.554545};
    double f[]= {1,2};
    double Q1[]={10.0,25.0,50.0};
    int axis1[]={1,2,3};
    int dl1=4;
    double sR1=1024.0;
    psvel(*lc,*f,*Q1,axis1,dl1,sR1);
    Py_Finalize();
}
第一个错误在第二个参数的位置\uuuPyx\uMemViewSlice突出显示,第二个错误(关于标识符)在第一次出现“int”时突出显示。)


我使用了memory view(基于Cython关于速度的文档。除此之外,我甚至不知道为什么要使用它。如果有人能告诉我从C调用cdef函数的正确方法,这将非常有用。

MemoryView提供了一种快速访问具有Python缓冲区接口的对象(例如Numpy数组)的方法.然而,它们并不是真正设计用于C语言,我也不知道一种简单的方法

我在这里可以想到两个选择:

  • 将Cython函数改为接受C指针。访问C指针很快(与MemoryView类似,可能更快)

  • 第二个
    cdef
    函数将C指针转换为memoryview。这样做的好处是,您仍然可以使用Numpy数组轻松调用memoryview函数,并且保留了memoryview的一些优点(例如自动边界检查)。要将指针投射到memoryview,您需要指针及其长度:
    ptr

    # no longer public - you're not calling it from C
    cdef psvel(double [:] lcfarray, double [:] fn,double [:]
             Q,int axis, int dl, double sR):
        # ...
    
    cdef public psvel_from_c(double * lcfarray, double * fn,double *
             Q,int axis, int dl, double sR):
        return psvel(<double[:len_of_lcfarray]>lcfarray,
                     <double[:len_of_fn]>fn,
                     # etc....
                     axis, dl, sR)
    
    #不再公开-您不是从C调用它
    cdef pLevel(双[:]lFarray,双[:]fn,双[:]
    Q、 int轴、int dl、双sR):
    # ...
    cdef公共psvel_来自_c(双*lcfarray,双*fn,双*
    Q、 int轴、int dl、双sR):
    返回pLevel(lcfarray,
    fn,
    #等等。。。。
    轴(左、右)
    

  • cdef public psvel_from_c(double*lcfarray,double*fn,double*Q,int axis,int dl,double sR):返回psvel(lcfarray,fn,Q,axis,dl,sR)^---------------------------------------------------------------pvel.pyx:20:17:无法分配类型“double[::1]'到'double*',您确实保留了
    psvel
    接受MemoryView(但删除了“public”?)。另外,您不需要执行
    等操作,因为这些类型已经正确了。是的,我确实保留了psvel并从psvel中删除了public,正如您发布的那样。我也删除了。我再次运行了它,失败是一样的:pvel.pyx:20:17:无法将类型“double[::1]”分配给“double*”我有
    cdef psvel(double[:]lcfarray,double[:]fn,double[:]Q,int轴,int-dl,double-sR):通过
    然后
    cdef-public-psvel_(double*lcfarray,double*fn,double*Q,int轴,int-dl,double-sR):返回psvel(lcfarray,fn,Q,axis,dl,sR)
    这对我来说很好。顺序错了。我按照你的建议更改了它,它可以从.pyx编译为.so文件。
    cdef public psvel(double * lcfarray, double *  fn,double *
             Q,int axis, int dl, double sR):
    
    # no longer public - you're not calling it from C
    cdef psvel(double [:] lcfarray, double [:] fn,double [:]
             Q,int axis, int dl, double sR):
        # ...
    
    cdef public psvel_from_c(double * lcfarray, double * fn,double *
             Q,int axis, int dl, double sR):
        return psvel(<double[:len_of_lcfarray]>lcfarray,
                     <double[:len_of_fn]>fn,
                     # etc....
                     axis, dl, sR)