29

Is there any way to tell Cython compiler that param is function. Something like

  cpdef float calc_class_re(list data, func callback)
xander27
  • 3,014
  • 8
  • 30
  • 42
  • If all else fails, you could probably piggyback on a C `typedef`. There may be a better, pure-Cython way though. –  Jan 02 '13 at 15:05
  • Do you mean a python function or a c function? comment by "delnan" will work for c when function signature is known. – shaunc Jan 03 '13 at 22:16
  • 2
    For a `cdef` or `cpdef` function, the C-style functype should work. Like `ctypedef (*my_func_type)(object, int, float, str)`. You need to use the `object` type for pure-python functions. – Niklas R Jan 03 '13 at 22:32
  • "For a cdef or cpdef function, the C-style functype should work." @NiklasR, can you give detailed example in answer, pls? – xander27 Jan 04 '13 at 05:36

1 Answers1

45

Should be self-explanatory..? :)

# Define a new type for a function-type that accepts an integer and
# a string, returning an integer.
ctypedef int (*f_type)(int, str)

# Extern a function of that type from foo.h
cdef extern from "foo.h":
    int do_this(int, str)

# Passing this function will not work.
cpdef int do_that(int a, str b):
    return 0

# However, this will work.
cdef int do_stuff(int a, str b):
    return 0

# This functio uses a function of that type. Note that it cannot be a
# cpdef function because the function-type is not available from Python.
cdef void foo(f_type f):
    print f(0, "bar")

# Works:
foo(do_this)   # the externed function
foo(do_stuff)  # the cdef function

# Error:
# Cannot assign type 'int (int, str, int __pyx_skip_dispatch)' to 'f_type'
foo(do_that)   # the cpdef function
Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • Should use `extern from "foo.h":` ? Is it compulsory? If we want to just pass a user-defined python function to cython function, is this sample code ok? If function is in another file and we want to pass it to a class as argument and call it multiple time in different methods of class, will this work? – Reza Akraminejad Jan 16 '22 at 21:17