I was working on creating on-the-fly images for a web application that I’m working on and off lately. I had made a method that called imagemagick using (run-program). This worked fine when I was running with one thread, but when I was using hunchentoot to serve it, threads were hanging up and acting flaky.
I went back to the drawing board and tried my hand at using FFI with Clozure. I was pleasantly suprised by what I found.
Clozure uses something called interface directories and comes with a few of these installed. You have to have the directories set up before you wan work with the FFI interface and that is what I’m going to cover in this post.
The first thing to know is that you need to have the ffigen4 tool installed. It wasn’t so easy to find the directions on installing this, but once you find them, it wasn’t too hard to get installed.
This installs a shell command h-to-ffi.sh that is used in the next step.
In order to use these you need to go to the ccl install directory (I just have it in my home directory) and go to the headers file that describes what version of CCL you are using. I’m using 64 bit CCL on linux so for me it would be ~/ccl/x86-headers64
you will see a few directories already installed there. Since I’m wanting to work with ImageMagick, I created an imagemagick directory and a C subdirectory per the instructions. The imagemagick directory should be all lowercase as CCL will later map a keyword to all lowercase to find the directory.
in the C directory, I created a new shell file populate.sh you must use this name exactly.
I put the following in the shell file:
#!/bin/sh
rm -rf ./home
h-to-ffi.sh -I/home/admin/ImageMagick-6.5.8-10 /home/admin/ImageMagick-6.5.8-10/magick/MagickCore.h
h-to-ffi.sh -I/home/admin/ImageMagick-6.5.8-10 /home/admin/ImageMagick-6.5.8-10/wand/MagickWand.h
h-to-ffi.sh -I/home/admin/ImageMagick-6.5.8-10 /home/admin/ImageMagick-6.5.8-10/wand/magick-wand-private.h
In most cases you can grab your header files out of your normal include directory (i.e. /usr/include) but because ImageMagick doesn’t install magick-wand-private.h, I needed to use the source directory for everything.
This is specific to ImageMagick, but I had to edit the magick-wand-private.h to include the line:
#include
at the top so that it could find all of the correct symbols.
once this is done, we can start up ccl and do the following (documented here):
?(require "PARSE-FFI")
PARSE-FFI
? (ccl::parse-standard-ffi-files :imagemagick)
note the double colons in the last statement, its not an exported function.
Assuming all went well you can now do the following
(use-interface-dir :imagemagick)
(open-shared-library "libMagickWand.so")
(setf wand (#_NewMagickWand))
and that will have to do until the next post.