6

一些 SciPy 函数(如scipy.ndimage.interpolation.geometric_transform)可以将指向 C 函数的指针作为参数,以避免在输入数组的每个点上调用 Python 可调用函数。

简而言之 :

  • 定义一个my_function在 C 模块中某处调用的函数
  • 返回PyCObject带有&my_function指针的 a 和(可选)void*用于传递一些全局数据的指针

相关的 API 方法是PyCObject_FromVoidPtrAndDesc,您可以阅读Extending ndimage in C来查看它的实际效果。

我对使用 Cython 使我的代码更易于管理非常感兴趣,但我不确定我应该如何创建这样的对象。任何,嗯,...指针?

4

2 回答 2

1

只需在 Cython 中执行与在 C 中相同的操作,PyCObject_FromVoidPtrAndDesc直接调用即可。这是您移植到 Cython 的链接中的示例:

###### example.pyx ######

from libc.stdlib cimport malloc, free
from cpython.cobject cimport PyCObject_FromVoidPtrAndDesc

cdef int _shift_function(int *output_coordinates, double* input_coordinates,
            int output_rank, int input_rank, double *shift_data):
    cdef double shift = shift_data[0]
    cdef int ii
    for ii in range(input_rank):
        input_coordinates[ii] = output_coordinates[ii] - shift
    return 1

cdef void _shift_destructor(void* cobject, void *shift_data):
    free(shift_data)

def shift_function(double shift):
    """This is the function callable from python."""
    cdef double* shift_data = <double*>malloc(sizeof(shift))
    shift_data[0] = shift
    return PyCObject_FromVoidPtrAndDesc(&_shift_function,
                                        shift_data,
                                        &_shift_destructor)

性能应该与纯 C 版本相同。

请注意,Cyhton 要求操作员&获取函数地址。此外,Cython 缺少指针取消引用运算符*,而是使用等效的索引 ( *ptr-> ptr[0])。

于 2013-05-09T11:56:26.883 回答
0

我认为这是个坏主意。创建 Cython 也是为了避免编写 PyObjects!此外,在这种情况下,通过 Cython 编写代码可能不会改善代码维护......无论如何,您可以使用导入 PyObject

from cpython.ref cimport PyObject

在您的 Cython 代码中。

更新

from cpython cimport *

更安全。

干杯,戴维德

于 2013-05-08T18:56:22.757 回答