0

I am trying to have c++ calling a callback function written in cython (function pointer). But the values I got inside Cython from C++ seems to be garbage value, and results in a seg fault.

Here is the code snippet

Inside C++

typedef void (*callback)(float *vec);

class CppClass{
  void set_callback(callback c) { this->c = c; }
}

// when needed inside CppClass
this->c(vec);

Then, I have a C++ wrapper (so I don't need to define too many complicated stuff inside Cython) to accept the callback from Cython and create CppClass

void wrapper(callback c) {
  CppClass *cls = new CppClass();
  cls->set_callback(c);
}

For the Cython part, what I have

cdef extern from "wrapper.h":
  cdef void wapper(void (*callback)(float*))

ctypedef void (*callback_t)(float*)

cdef class CyClass:
  cdef void init(self):
    wrapper(<callback_t>&CyClass.callback)
  cdef void callback(self, float *vec):
    print(vec[0])

Now the Cython callback is called successfully (every 1s in fact), but the issue is the float* seems to be different / corrupt; I tried to pass in int in similar way and the value is also very different (garbage value in Cython)

Can someone please help?

cocomac
  • 518
  • 3
  • 9
  • 21

1 Answers1

0
wrapper(<callback_t>&CyClass.callback)

The fact you have the cast is telling you that something is wrong here. Namely that CyClass.callback has completely the wrong signature. It actually takes two arguments - a CyClass pointer and a float pointer.

You might be tempted to try to use a bound cdef method. This won't work either - a C function pointer simply had no where to store any extra data.

See https://stackoverflow.com/a/68326277/4657412 for a similar question that proposes some possible solutions (none of which are hugely satisfactory)

DavidW
  • 29,336
  • 6
  • 55
  • 86