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 ( *ptr → ptr[0] ).
source share