Domanda

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.

È stato utile?

Soluzione

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top