Ваша функция 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)
В качестве примечания: если у вас есть только фиксированное количество потенциальных указателей на функции для рассмотрения, я бы рассмотрел использование enum вместо операторов 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)