I can't think of anything useful you can do with an array of function pointers of unknown type - it isn't safe to call them (since you don't know the signature) and there really isn't anything else to do with function pointers. Therefore you at least need to find some way of storing what type of pointer it is.
One option would be to store a struct containing both pointers:
cdef struct FuncPtrStruct:
func2param f2p
func3param f3p
You then set one to NULL
, store in the other one, and only call the non-NULL
one The array specification would then be similar to cdef FuncPtrStruct array[10]
.
However, I'd probably use a C Union instead to store both pointers in the same memory location (+ an enum to identify the type). This is a little more effort to set up (you need an enum
to define the type of the union
, the union
itself, and a struct
containing the enum
and the union
); however the advantage is that you can add a lot more different types of function pointers without using more memory (for the "two-type" case the memory is probably equal):
# cpdef if you want to use the enum from Python too
cdef enum FuncType:
twoArg, threeArg
cdef union FuncPtrUnion:
func2param f2p
func3param f3p
cdef struct FuncPtrHolder:
FuncType type_
FuncPtrUnion value
Just to illustrate how you'd use it:
cdef long f(long x1, long x2):
print("f",x1,x2)
return 0
cdef long g(long x1, long x2, long x3):
print("g",x1,x2,x3)
return 1
def example():
cdef FuncPtrHolder fArray[10]
for i in range(10):
if i%2:
fArray[i].type_ = twoArg
fArray[i].value.f2p = &f
else:
fArray[i].type_ = threeArg
fArray[i].value.f3p = &g
# use
for i in range(10):
if fArray[i].type_ == twoArg:
fArray[i].value.f2p(i,i+1)
elif fArray[i].type_ == threeArg:
fArray[i].value.f3p(i,i+1,i+2)
It looks like in your code you have some list
of Python objects and this is why you're getting compile errors. Without code it's impossible to know why, but I think Cython can automatically generate Python wrappers for cdef
functions so I'd guess you've somehow made a list of those wrappers. If you want to handle Python lists of FuncPtrHolder
(or otherwise use it from Python) you'd have to wrap it in a cdef class
.
In this case my preferred, simpler solution would probably be to just use func3param
and have the "two parameter" functions simply ignore the third argument. This means all the function pointers would have a consistent signature, which would make a lot more sense to me.