我有一个用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)
然而,这不起作用。我怎么能这样做?
答案 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。