Cython 创建 C 函数别名
Posted
技术标签:
【中文标题】Cython 创建 C 函数别名【英文标题】:Cython Create C Function Alias 【发布时间】:2019-06-21 17:40:39 【问题描述】:我有两个函数的变体: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
或者,我尝试使用产生相同错误的 dicts:
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]'
【问题讨论】:
【参考方案1】:您的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)
【讨论】:
unordered_map 正是我想要的,它非常适合我的情况。以上是关于Cython 创建 C 函数别名的主要内容,如果未能解决你的问题,请参考以下文章