Cython throws an error when pass function with void * argument to dict

落花浮王杯 提交于 2020-01-06 05:38:26

问题


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 code raises an Error: Cannot convert 'void (void *)' to Python object Any ways to overcome this problem?


回答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
        return out

Then you can simply do:

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



回答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.:

cpdef void foo(const char * bar):
    pass

cdef dict 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

cdef void foo(void *bar):
    pass

ctypedef void (*f_type)(void *)

cdef unordered_map[string, f_type] foobar

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


来源:https://stackoverflow.com/questions/57461648/cython-throws-an-error-when-pass-function-with-void-argument-to-dict

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!