I'm building an interpreter for a dynamic programming language in Haskell. I'd like to add a simple mechanism to call C functions. In the past, I've used the Haskell FFI to call C functions that I had explicitly declared the name and type of; this approach won't work here because the interpreter won't know the name or type of the C functions to be called until runtime.
Is it possible to declare and call C functions at runtime? Where should I begin?
If you can list all possible types for the C functions that may be called, then you can use the FFI's dynamic import capability ( http://www.haskell.org/onlinereport/haskell2010/haskellch8.html). A dynamic import function wraps a C function at runtime. You'll need to declare an import function for each C function type that you may be calling. (Actually, only the ABI matters, so you can treat all C pointer types as equivalent.)
foreign import ccall "dynamic" mkPtrFun :: FunPtr (Ptr () -> IO (Ptr ())) -> Ptr () -> IO (Ptr ())
If you have a pointer to a C function, you can make it callable from Haskell using this wrapper function.
callWithNull :: FunPtr (Ptr a -> IO (Ptr ())) -> IO (Ptr ())
callWithNull f = mkPtrFun f nullPtr
If the types of the C functions are unknown when the Haskell code is compiled, then you cannot do this with the FFI.
As for obtaining C function pointers dynamically, the FFI doesn't help you. You can use dynamic loading libraries in C such as libdl. See the man pages: http://linux.die.net/man/3/dlopen .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With