Cython: How to expose void* and function pointer in struct?
Question: I have a C header with:

    
    
    typedef struct
    {    
          <normal members>
          void (*cb_func)(glp_tree *T, void *info);
          void *cb_info;
          <normal members>
    } glp_iocp;
    

Currently, in my pxd file:

    
    
    ctypedef struct IntOptCP "glp_iocp":
        <normal members>
        int out_dly     #  mip.out_dly (milliseconds)
        #void (*cb_func)(Tree* tree, void* info)
                        #  mip.cb_func
        #void* cb_info   #  mip.cb_info
        <normal members>
    

In a pyx file, at some point, I do (essentially):

    
    
    cdef class MyClass:
    
        IntOptCP _iocp
    
        <__cintit__ and the like>
    
        def some_method(self):
            <manipulation of self._iocp>
            controls = dict()
            controls = self._iocp
            return controls
    

This works nicely. However, now I also wish to expose `cb_func` and `cb_info`.
This then breaks the assignment to controls. What I would like to have is two
python object types (classes?), one for `cb_func` and one for `cb_info`,
instances of which can be passed through to `cb_func` and `cb_info` arguments
of the `glp_iocp` struct.

I have read <https://github.com/cython/cython/tree/master/Demos/callback> (and
have used pycapsule), but nevertheless, I am too inexperienced/unfamiliar with
Cython to see how I can use that information for my specific case.

So, any help and pointers on how to (best) expose `cb_func` and `cb_info` are
welcome.


Answer: It seems you can expose `cb_func` and `cb_info` doing something similar to
this toy example:

    
    
    import numpy as np
    cimport numpy as np
    
    ctypedef void (*f_type)(int, double*, double*)
    
    ctypedef struct IntOptCP:
        int a
        double *b
        double *c
        f_type f
    
    cdef class MyClass:
        cdef IntOptCP _iocp
        def exec_f(self):
            self._iocp.f(self._iocp.a, self._iocp.b, self._iocp.c)
    
    cdef void myfunc(int a, double *b, double *c):
        cdef int i
        for i in range(a):
            b[i] += 1
            c[i] += 1
    
    def main():
        cdef f_type f
        cdef np.ndarray[np.float64_t, ndim=1] b, c
        cdef int a
        a = 100
        b = np.zeros(a, dtype=np.float64)
        c = np.zeros(a, dtype=np.float64)
        test = MyClass()
        test._iocp.a = a
        test._iocp.b = &b[0]
        test._iocp.c = &c[0]
        test._iocp.f = myfunc
        print 'before', a, b, c
        test.exec_f()
        print 'after', a, b, c
    

