如何在C程序的内存视图中调用Cython的cdef函数?

时间:2019-02-03 00:17:34

标签: 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 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();
}

在Xcode中编译main.c时,出现以下错误:

1。在pvel.h中重新定义参数'_Pyx_memviewslice'

  1. 期望的标识符pvel.h

当我单击错误时,编译器会在以下行中突出显示pvel.h文件中的错误:

__PYX_EXTERN_C PyObject *psvel(__Pyx_memviewslice, __Pyx_memviewslice,   __Pyx_memviewslice, int, int, doublevoid);

第一个错误在第二个参数的位置__Pyx_memviewslice突出显示,第二个错误(关于标识符)在第一次出现'int'时突出显示

我使用了内存视图(基于Cython的文档以提高速度。除此之外,我不确定为什么还要使用它。如果有人可以向我展示从C调用cdef函数的正确方法,这将很有帮助。

1 个答案:

答案 0 :(得分:1)

Memoryviews提供了一种快速的方法来访问具有Python缓冲区接口的对象(例如Numpy数组)。但是,它们并不是真正为C语言设计的,并且我不知道一种简单的方法。

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

  1. 将您的Cython函数更改为接受C指针。访问C指针的速度很快(类似于memoryviews,可能更快)

    cdef public psvel(double * lcfarray, double *  fn,double *
             Q,int axis, int dl, double sR):
    
  2. 具有第二个cdef函数,该函数将C指针转换为memoryviews。这样做的好处是您仍然可以轻松地用Numpy数组调用memoryview函数,并且保留了memoryview的一些优点(例如自动边界检查)。要将指针强制转换为memoryview,您需要指针及其长度:<double [:length]>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)