我正在尝试创建一个依赖Python函数的Cython函数。这个Python函数的参数包括一个float和一个数组(我正在使用Numpy数组)。我尝试遵循此示例Python/Cython/C and callbacks, calling a Python function from C using Cython,但在尝试访问传递给Python函数的数组时,我的代码出现了段错误。 我必须做一个回调函数,因为我不能直接将Python函数传递给C函数。 下面是一个最小的示例(我的代码比该示例更复杂,但问题是相同的)
example.py:
import numpy as np
from example_cython import my_function
def python_fun(x, x_arr):
"""
Add x to the elements of x_arr
"""
x_arr += x
return 0.0
A = np.arange(3.)
B = np.ones(3, dtype=np.float)
n = 3
x = 2.
# Call the C function using the Python one
my_function(A, B, n, x, python_fun)
example.c
#include<stdio.h>
// Add x to the elements of *a and then add the elements of *a to *b
void C_fun(double * a, double * b, int n, double x,
double (*f) (double, double *)
) {
printf("a: %f b: %f x: %f\n", a[0], b[0], x);
// Update array a
f(x, a);
for(int i=0; i<n; i++) b[i] += a[i];
}
example.h
void C_fun(double * a, double * b, int n, double x,
double (*f) (double, double *)
);
example_cython.pyx
# Function prototype for the C function
ctypedef double (*cfunction)(double x, double * y)
cdef object f
cdef extern from "example.h":
void C_fun(double * a, double * b, int n, double x,
double (*f) (double, double *)
)
cdef double cfunction_cb(double x, double [:] y):
global f
result = f(x, y)
return result
# This function calls the f function (a Python f) that updates *a and then sums
# the elements of *a into *b
def my_function(double [:] a, double [:] b, int n, double x, pythonf):
global f
f = pythonf
C_fun(&a[0], &b[0], n, x, <cfunction> cfunction_cb)
setup.py
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
extension_src = ["example_cython.pyx", "example.c"]
extensions = [
Extension("example_cython", extension_src)
]
setup(
ext_modules=cythonize(extensions),
)
编译Cython模块有效,我可以访问C函数并打印数组内容,但是当该函数调用数组时,就会出现问题
a: 0.000000 b: 1.000000 x: 2.000000
[1] 791 segmentation fault (core dumped) python example.py