This is tricky (at least to me :-) , maybe unfeasible. But I try to ask to you.
I have this c shared library:
#include <stdio.h>
#include <stdlib.h>
static int variable = -666;
int get_value() {
return variable;
}
void print_pointer_to_get_value() {
printf("pointer_to_get_value: %p\n", &get_value);
}
Compiled this way (on Linux):
gcc -fPIC -c -O2 shared.c && gcc -shared -o shared.so shared.o
Now I load the library and call print_pointer_to_get_value():
>>> import ctypes
>>> so = ctypes.cdll.LoadLibrary('./shared.so')
>>> so.print_pointer_to_get_value()
pointer_to_get_value: 0x7f46e178f700
I'd like to get from ctypes the actual address, as integer, of the get_value function as printed by print_pointer_to_get_value(). My final target is to move that address to a Cython module and call that function inside a "nogil" Cython function. I need to load the .so library at runtime, therefore I cannot compile my Cython module linking it to the library.
Thanks 1000.
It's a nasty multistep process that isn't easy to do elegantly:
Some Cython code:
ctypedef double (*math_function_t)(double) nogil
import ctypes
def call_f(f, double x):
cdef math_function_t cy_f_ptr = (<math_function_t*><size_t>ctypes.addressof(f))[0]
cdef double res
with nogil:
res = cy_f_ptr(x)
return res
Here I pass Cython a Ctypes function type (f
) and get the address in Cython. I don't think it's possible to obtain the address in Python. As an example of how you might initialise f
, on Linux you could do:
lib = ctypes.cdll.LoadLibrary("libm.so.6")
f = lib.sin
call_f(f,0.5) # returns sin(0.5)
(to use the standard library sin
function).
The Cython line cdef math_function_t cy_f_ptr = (<math_function_t*><size_t>ctypes.addressof(f))[0]
can be broken down as follows:
ctypes.addressof(f)
gets the address that the ctypes
variable f
is held in. __This is NOT the value you're after_ - it's the place where the value you're after is stored.size_t
integer then to a pointer to a cdef
function pointer type. Cython requires the two step cast.[0]
dereferences your math_function_t*
to get a math_function_t
. This is the function pointer (i.e. the value you want)The information for this answer was got from this newsgroup thread (which I can't currently access)