如何在Cython中使用C编写的函数

时间:2013-11-27 02:18:29

标签: python c numpy cython

我有一个用C编写的函数,存储在两个文件中;头文件和c文件。 cython文档只提到如何将内置的C函数引入cython,例如stdio和stdlib。这就是我想要做的事情:

from numpy import *


dir = loadtxt('cell_dirs_001.txt')
spk = loadtxt('cell_spks_001.txt')
pout = zeros(9)


cdef extern from "platemethod.h":
    double platemethod(double dir, double spk, 7, double pout)

其中dir和spks都是5x8双精度数组。我会发布platemethod文件,但函数本身大约有200行。相反,让我们用一个更简单的例子来做。假设我有一个C函数来测试数字的素数,所以我创建的两个文件让它们称为fib.c和fib.h。这是fib.h:

void fib(int n)

那里并不多,甚至可能没有必要。然而,大功能有一个标题,所以我们假装它是必须的。这是fib.c:

#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include "fib.h"

void fib(int n){
    int n;
    int i = 2;    /* Obviously 1 can divide all and 2 is the base of primality*/
    while (i < n) {
        if (n % i == 0){
        return 0;
        break;
    }
        else {
        i = i + 1;
        if (i == (n-1)){
            return 1;
        }
    }

}

return 0;
} 

现在让它变得有趣,说我想通过一个数字列表,看看它们是否是素数。

a = [5,12,787,2,53334,12353112,12112478]
cdef extern from "fib.h":
    for n in a:
        print fib(n)

然而,这不起作用。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

您必须基本上重复.pyx.pxd文件中的标题(.h),并在必要时进行相应的更改。

用你更简单的例子,我不得不改变一点。 C代码存在一些问题(在函数内返回int但声明为void,此案例中所有包含都是不必要的。)

int fib(int n){
    int i = 2;    /* Obviously 1 can divide all and 2 is the base of primality*/
    while (i < n) {
        if (n % i == 0){
            return 0;
            break;
        }
        else {
            i = i + 1;
            if (i == (n-1)){ return 1; }
        }
    }
    return 0;
} 

您的标题在定义后应该有;

void fib(int n);

Cython文件类似于(我称之为my_cython.pyx):

cdef extern from './fib.h':
    int fib(int n)

cdef extern from './fib.c':
    pass

def function(n):
    return fib(n)

然后,在编译之后,从普通的Python脚本:

from my_cython import function
print function(10)

cdef extern from *:Cython's "Tricks and Tips"中解释的技巧。有时您必须添加:

cdef extern from *:
    pass

答案 1 :(得分:-1)

您需要在包含中包含Python.h。 您还需要将fibo声明为返回类型静态PyObject *而不是void。

请参阅:http://docs.python.org/2/extending/extending.html