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

2024-04-29 19:58:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个用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和spk都是5x8双精度数组。我会发布platemethod文件,但函数本身大约有200行长。让我们用一个更简单的例子。假设我有一个C函数来测试一个数的素性,那么我创建的两个文件分别称为fib.C和fib.h。这里是fib.h:

^{pr2}$

那里不多,可能甚至没有必要。但是大函数有一个头,所以我们假设它是必须的。以下是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)

但这不起作用。我该怎么办?在


Tags: 文件函数fromreturnincludedircellspk
2条回答

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

参见:http://docs.python.org/2/extending/extending.html

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

对于你的简单例子,我不得不稍微改变一下。C代码有一些问题(在函数内部返回int,但将其声明为void,对于这种情况,所有的include都是不必要的。)

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;
} 

您的头在定义之后应该有一个;

^{pr2}$

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

相关问题 更多 >