15.12 Convert a function pointer to a callable object?
You've got a memory address for a compiled function that you want to convert to a Python callable object,
In this case you can use it as an extension function.
Solution?
ctypes
The module can be used to create a Python callable object that wraps any memory address.
The following example shows how to get the original, underlying address of a C function, and how to convert it to a callable object:
>>>ImportcTYPES>>>Lib=cTYPES.Cdll.LoadLibrary(None)>>># Get The address of sin () from the C math library>>>Addr=cTYPES.Cast(Lib.Sin,cTYPES.C_void_p).Value>>>Addr140735505915760>>># Turn the address into a callable function>>>Functype=cTYPES.Cfunctype(cTYPESc_doublectypes. C_double) >>> func = Functype (addr) >>> Func<cfunctiontype object at 0x1006816d0>>>> # Call the resulting Function>>> func (2< Span class= "P" >) 0.9092974268256817>>> func (0) 0.0>>>
Discuss?
To build a callable object, you first need to create an CFUNCTYPE
instance.
CFUNCTYPE()
The first parameter is the return type.
The next parameter is the parameter type. Once you have defined the function type, you can wrap it around an integer memory address to create a callable object.
The resulting object is used as a normal ctypes
accessible function.
This section may look a bit cryptic, slightly below the bottom.
However, it is widely used in a variety of advanced code generation techniques such as instant compilation, which can be seen in the LLVM function library.
For example, here is a llvmpy
simple example of using an extension to build a small aggregate function, get its function pointers,
and converts it to a Python callable object.
>>>FromLlvm.coreImportModule,Function,Type,Builder>>>MoD=Module.New(' Example ')>>>F=Function.New(MoD,Type.function(Type.Double(),[Type.double (), type.double ()], False), ' foo ')>>>Block=F.Append_basic_block(' Entry ')>>>Builder=Builder.New(Block)>>>X2=Builder.Fmul(F.Args[0],F.Args[0])>>>Y2=Builder.Fmul(F.Args[1],F.Args[1])>>>R=Builder.Fadd(X2,Y2)>>>Builder.Ret(R)<llvm.core.instruction Object at 0x10078e990>>>>Fromllvm.eeImportExecutionengine>>>Engine=Executionengine.New(MoD)>>>Ptr=Engine.Get_pointer_to_function(F)>>>Ptr4325863440>>>Foo=cTYPES.Cfunctype(cTYPES.C_double,cTYPES.c_doublectypes. C_double) (ptr) >>> # Call the resulting Function>>> foo (2< Span class= "p" >,3) 13.0>>> foo (4,5) Span class= "Go" >41.0>>> foo (1 ,2) 5.0>>>
It's not that making any mistakes at this level will cause the Python interpreter to hang up.
Remember that you are dealing directly with machine-level memory addresses and local machine code, not Python functions.
Albert (http://www.aibbt.com/) The first artificial intelligence portal in China
Python Cookbook (3rd edition) Chinese version: 15.12 Convert a function pointer to a callable object