Note that there are some explanatory texts on larger screens.

plurals
  1. POCython - implementing callbacks
    primarykey
    data
    text
    <p>I have been working with Cython in an attempt to interface with a library written in c++. So far things are going pretty good, and I can effectively use MOST functions within the library. My only problem lies within implementing callbacks. The library has 4 function definitions that look a little something like this:</p> <pre><code>typedef void (*Function1)(const uint16_t *data, unsigned width, unsigned height); void SetCallBack(Function1); </code></pre> <p>So to implement them I figured I would do something like this with cython:</p> <pre><code>ctypedef void (*Function1)(unsigned short *data, unsigned width, unsigned height); cdef extern from "lib.hpp": void SetCallBack(Function1) </code></pre> <p>Which actually compiles correctly, however, I can't for the life of me think how to actually implement that in such a way that the callback would work. I first tried creating a function that would just call that, similar to how you would do it for any other function, coming up with this:</p> <pre><code>def PySetCallBack(Func): SetCallBack(Func) </code></pre> <p>but that gives me the (predictable) error: </p> <p>"Cannot convert Python object to 'Function1'"</p> <p>so yeah, that's where I'm at. If anyone has any experience setting up callbacks in Cython I would be very grateful for any assistance. Thanks.</p> <p><strong>Edit</strong>: Following your advice, I created an intermediate function with a cdef, which looks like this:</p> <pre><code>cdef void cSetCallBack(Function1 function): SetCallBack(function) </code></pre> <p>This seems to have gotten me... Closer? Getting a different error now at least:</p> <pre><code>error: invalid conversion from ‘void (*)(short unsigned int*, unsigned int, unsigned int)’ to ‘void (*)(const uint16_t*, unsigned int, unsigned int)’ </code></pre> <p>Now, far as I can tell those types are identical, so I can't figure what's going on.</p> <p><strong>Edit2</strong>: Fixed that problem by declaring a new typedef:</p> <pre><code>ctypedef unsigned short uint16_t </code></pre> <p>and using that as the argument to call, but apparently that wasn't actually getting any closer, but just taking me around a side track, since when trying to call that function, I get the same "Cannot convert Python object to 'Function1'" error all over again.</p> <p>So, I'm pretty much back where I started. Only thing I can figure to do now is explicitly cast the python object coming in as a c function like that, but, to be honest, I have no idea how I would go about that.</p> <p><strong>Edit the third</strong>: Alright, after dissecting your answer I finally get it, and it works, so hooray and whatnot. What I ended up doing was creating a function like this:</p> <pre><code>cdef void cSetCallback(Function1 function): SetCallback(function) cdef void callcallback(const_ushort *data, unsigned width, unsigned height): global callbackfunc callbackfunc(data,width,height) cSetCallback(callcallback) def PySetCallback(callbackFunc): global callbackfunc callbackfunc = callbackFunc </code></pre> <p>So now the only problem is that it can't convert const_ushort *data into a python object, but that's another problem entirely, so I guess this one is solved, thanks a lot.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload