我有一个函数的两个变体:void func1(double *)
和void func2(double *)
,它们是C ++代码提供的。
我希望能够编写一个包装它们的函数或映射:
cdef func_alias(int choice):
if choice == 0:
return func1
elif choice == 1:
return func2
但是编译Cannot convert 'void (double *) nogil' to Python object
或者,我尝试使用会产生相同错误的字典:
cdef dict func_dict = {0: func1, 1: func2}
但是我遇到同样的错误。
我不确定是否可以按照
from libcpp.map import map
cdef map[int, void] func_map = {0: func1, 1: func2}
产生Cannot interpret dict as type 'map[int,void]'
答案 0 :(得分:2)
您的func_alias
函数未定义返回类型(这意味着它将默认为python对象)。由于函数指针不是有效的python对象,因此cython会在编译时为您提供该错误消息。我们可以定义一个表示函数指针的ctypedef
并将其用作返回类型。这是一个执行此操作的示例:
ctypedef void (* double_func)(double *)
cdef void func_1(double *arg1):
print(1, arg1[0])
cdef void func_2(double *arg1):
print(2, arg1[0])
cdef double_func func_alias(int choice):
if choice == 1:
return func_1
elif choice == 2:
return func_2
cdef double test_input = 3.14
func_alias(1)(&test_input)
func_alias(2)(&test_input)
作为一个补充说明,如果您只考虑固定数量的潜在函数指针,则可以考虑使用一个枚举代替if语句。如果有帮助,我可以举一个例子。让我知道是否有任何不清楚的地方。
更新:
查看问题的第二部分,我发现您还在考虑使用哈希映射将整数映射到函数指针。尽管您不能使用dict
来执行此操作,因为它们只能存储python对象,但是您可以使用map
(或unordered_map
,应该会稍微好一些)。不幸的是,您不能使用方便的python dict语法初始化dict的所有值,而必须一个接一个地添加项。这是正在起作用的方法:
from libcpp.unordered_map cimport unordered_map
ctypedef void (* double_func)(double *)
cdef unordered_map[int, double_func] func_map
func_map[1] = func_1
func_map[2] = func_2
cdef void func_1(double *arg1):
print(1, arg1[0])
cdef void func_2(double *arg1):
print(2, arg1[0])
cdef double_func func_alias(int choice):
return func_map[choice]
cdef double test_input = 3.14
func_alias(1)(&test_input)
func_alias(2)(&test_input)