Skip to content Skip to sidebar Skip to footer

Cython Throws An Error When Pass Function With Void * Argument To Dict

I have a function with void * parameter and I want to store it in the dict. What I do is: %%cython cdef void foo(void * bar): pass cdef dict foobar = {'foo': foo} But this

Solution 1:

The easiest solution is to create a cdef class that can wrap this function. Since the cdef class is a Python object it can be stored in a dictionary like any other Python object.

ctypedef void (*void_func_ptr)(void*)

cdef class VoidFuncWrapper:
    cdef void_func_ptr func
    def __cinit__(self):
       self.func = NULL

    @staticmethod
    cdef VoidFuncWrapper make_from_ptr(void_func_ptr f):
        cdef VoidFuncWrapper out = VoidFuncWrapper()
        out.func = f
        returnout

Then you can simply do:

cdef dictfoobar= {'foo': VoidFuncWrapper.make_from_ptr(foo)}

Solution 2:

Your problem here is that void* has no defined converter from a Python object, so a Python wrapper function (that accepts Python objects, converts them, and passes them to the underlying C function) can't be defined, either explicitly with cpdef or implicitly by putting the cdef function in a Python object (the dict in this case).

You could make this work by defining the argument to be something Cython knows how to convert to, e.g.:

cpdefvoid foo(const char * bar):
    pass

cdefdict foobar = {'foo': foo}

Try it online!

But that may not work for your scenario if the function needs to accept an arbitrary pointer. If that's the case, you may want to switch to using C++ containers that can hold your function pointer type directly:

from libcpp.unordered_map cimport unordered_map
from libcpp.string cimport string

cdefvoid foo(void *bar):
    pass

ctypedefvoid (*f_type)(void *)

cdefunordered_map[string, f_type] foobar

foobar['foo'.encode('ascii')] = foo

Post a Comment for "Cython Throws An Error When Pass Function With Void * Argument To Dict"