GHC Runtime Loading

Note: Since I wrote this dynamic loader for Haskell a long time ago, quite a few advancements have been made, so I’m no longer supporting this package. See the end of the page for discussion on the state-of-the-art in Haskell dynamic loading.

Introduction to Dynamic Loading & Plugins

Dynamic Loading is an important feature for building extensible programs and larger applications. It allows the program to load in code contained in a file, at runtime, and execute it. It’s a simple concept, but it leads to applications which can be very easily extended, sometimes in ways the original author never imagined.

If you’re still not convinced of the power of dynamic loading, think of WinAmp (a.k.a. XMMS :), which uses plugins to read files and perform device-specific output (not to mention all of its fantastic visualisation plugins). Each file type (MP3, WAV, OGG, XM, etc) is handled by a separate plugin, which means that it’s incredibly easy to extend WinAmp to play different types of media files.

Other notable projects which extensively use plugins are the Linux kernel (think kernel modules), Emacs, the Windows device driver model, the entire DirectX/gstreamer media framework, and the Apache web server. These projects would not be what they are today without their modular, extensible design.

Plugins in Haskell

The good news is: GHC has had, for quite a while now, the capability to load in Haskell modules at runtime. (If you use GHCI, that’s exactly what it does!) The bad news is: you can’t normally get at the functions which will do this for you. The better news is: thanks to some handiwork, you now can get at the functions which perform runtime (un)loading of modules; you’ll need to download a special RuntimeLoader module which allows you to do this.

To use it,

  import RuntimeLoader

  ...

  -- Load the plugin file
  plugin <- loadObject "MyPlugin.so"

  -- Load the function inside the plugin
  adder <- loadFunction plugin "addFunction" :: IO (Int -> Int -> Int)

  -- Execute the function
  let i = adder 2 3

That’s all you need to do to load a plugin. (Okay, not quite, you have to add a few flags to the ghc commandline too ;-).

If you’re interested, I’ve packaged up a small, example program called “TextFilter” which includes the RuntimeLoader module and demonstrates how to use it. Download it and get hacking!

Sorry, there’s no separate package for just the RuntimeLoader by itself: I think the TextFilter example is small enough that packaging it separately from the RuntimeLoader isn’t worth the hassle for you or me.

RuntimeLoader Redux

Since the release of RuntimeLoader in 2002, a few other people have taken up the challenge to make Haskell a more dynamic language. If you’re interested in this, have a look at:

  • HWS-WP, a.k.a “Haskell Web Server With Plugins”. Martin Sjöaut;ren took the original Haskell Web Server written by Simon Marlow many moons ago, and extended it to have Apache-style modules.
  • Hampus Ram’s DynamicLoader, which provides a higher-level API than my RuntimeLoader module.
blog comments powered by Disqus