在Cython中创建PyCObject指针

时间:2013-05-08 13:23:42

标签: python c scipy cython

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

简而言之:

  • 在C模块的某处定义一个名为my_function的函数
  • 使用PyCObject指针和(可选)&my_function指针返回void*以传递一些全局数据

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

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

2 个答案:

答案 0 :(得分: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 - &gt; ptr[0])。

答案 1 :(得分:0)

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

导入PyObject
from cpython.ref cimport PyObject
在您的Cython代码中

更新

from cpython cimport *

更安全。

干杯, 的Davide