从Cython函数调用Python函数

时间:2019-02-21 22:14:43

标签: python c arrays cython

我正在尝试创建一个依赖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

0 个答案:

没有答案