Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call C Functions from Haskell at runtime

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?

like image 680
heyitsbmo Avatar asked Jul 18 '11 23:07

heyitsbmo


1 Answers

Dynamic Importing

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.

Dynamic Loading

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 .

like image 65
Heatsink Avatar answered Oct 10 '22 00:10

Heatsink