Creating a PyCObject Pointer in Cython

Several SciPy functions (for example, scipy.ndimage.interpolation.geometric_transform ) can take pointers to C functions as arguments to avoid the need for a Python call to be called at every point in the input array.

In a nutshell:

  • Define a function called my_function somewhere in the C module
  • Return a PyCObject using the &my_function pointer and (optionally) the void* pointer to pass some global data around

The associated API method is PyCObject_FromVoidPtrAndDesc , and you can read the ndimage Extension in C to see it in action.

I'm very interested in using Cython so that my code is more manageable, but I'm not sure how exactly I should create such an object. Any, well, ... pointers?

+6
source share
2 answers

Just do the same thing you would do in C in PyCObject_FromVoidPtrAndDesc , call PyCObject_FromVoidPtrAndDesc directly. Here is an example from your link placed in 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) 

Performance should be identical to pure C.

Note that Cyhton requires the & operator to get the address of the function. In addition, Cython does not have a * pointer reversal operator; instead, it uses the indexing equivalent ( *ptrptr[0] ).

+1
source

I think this is a bad idea. Cython was created to avoid writing PyObjects! Moreover, in this case, writing code through Cython probably does not improve code maintenance ... In any case, you can import PyObject with

 from cpython.ref cimport PyObject 

in your cython code.

UPDATE

 from cpython cimport * 

safer.

Cheers, Davide

0
source

Source: https://habr.com/ru/post/944526/


All Articles