Converting a function pointer to any other pointer type is undefined behaviour in C so not guaranteed to work (see last point of the linked answer). In practice function pointer to void*
is often OK. There is no good reason to store it as a pointer to a number though.
Looking at your code:
cdef void* ptr = getTestPtr() # getting the function pointer
cdef TEST mytest = <TEST> ptr # testing the function pointer
mytest() # still works here
You convert a function pointer to a void pointer and back to a function pointer. Probably OK, but not guaranteed.
cdef double** dPptr = <double**> ptr
Convert the function pointer to a pointer to a pointer to a double. Dodgy.
cdef double* dPtr = dPptr[0]
You de-reference the pointer. This gets you what is in the bit of memory the function is stored in (i.e. executable code). You pretend to interpret that executable code as a pointer to a double.
doubleArrayStorage[0] = dPtr[0] #storing in a given double array at index 0
dPtr[0]
looks up an arbitrary bit of memory that it picks by misinterpreting some executable code as a pointer to a double. I'm surprised it doesn't segmentation fault here. Having got the contents of an arbitrary bit of memory you store it in the address pointed to by doubleArrayStorage
(which you haven't told us about).
################################################
# starting of back conversion:
cdef double* dPtr2 = &doubleArrayStorage[0]
&doubleArrayStorage[0]
reads from then takes the address of doubleArrayStorage
. It's equivalent to just writing doubleArrayStorage
. You save that as a double pointer. This is just the location of doubleArrayStorage
(i.e. correctly a double pointer, but nothing to do with your original function).
cdef void** Pptr2 = <void**> dPtr2
You reinterpret the address of doubleArrayStorage
as a pointer to a pointer to a void.
cdef void* ptr2 = Pptr2[0]
You dereference that address. ptr2
contains whatever is in the first element of doubleArrayStorage
which you are pretending is a void*
. In reality it's the contents of an arbitrary bit of memory you read earlier.
cdef TEST mytest2 = <TEST> ptr2
mytest2() #SEGMENTATION FAULT !
You use the contents of that arbitrary bit of memory as a function pointer and try to execute it.
In summary, I don't believe there's any way to do what you're trying to do safely in C (which means Cython can't do it either).