[cffi-devel] New foreign library interface

Luís Oliveira luismbo at gmail.com
Wed Jan 4 21:08:00 UTC 2006


Hello,

There's been some discussion on IRC about what CFFI's "smarter" foreign
library interface should look like. I put together some code and here's
what my attempt looks like:

  (define-foreign-library opengl
    (:darwin  (:framework "OpenGL"))
    (:unix    (:alternatives "libGL.so" "libGL.so.1"
                             #p"/myhome/mylibGL.so"))
    (:windows "opengl32.dll")
    ;; and a hypothetical example of a particular platform
    ;; where the OpenGL library is split in two.
    ((:and :some-system :some-cpu) "libGL-support.lib" "libGL-main.lib"))


The library is then used with the following macro:

  (use-foreign-library opengl)


So here's what's going on when loading this opengl library:

  - First, the proper clause is selected in a cond-like fashion. The
    symbols in there are tested against symbols in *features* that
    belong to the cffi-features[1] package. The :and, :or and :not
    operators are supported.

  - Then, the rest of the elements in the clause are handled. There can
    be more than one. For example you could define GLUT and OpenGL in
    one define-foreign-library form and whatever support libraries those
    might need.

  - Each of the elements can be:

    a) A string, eg. "libGL.so". In this case it's passed to
       load-foreign-library directly. What this means in e.g. unix-like
       systems is that the library will be searched in:

         1. the LD_LIBRARY_PATH environment variable.
         2. the directories in /etc/ld.so.cache (or equivalent)
         3. /usr/lib and /lib

       If that fails, it tries to find it in the directories inside
       cffi:*foreign-library-directories* which is similar to
       asdf:*central-registry* in the sense that you can push
       stuff like '*default-pathname-defaults* or
       '(user-homedir-pathname) and they'll be "evaluated".

    b) A pathname, in which case CFFI doesn't try to find it and simply
       passes its namestring to load-foreign-library.

    c) A list of the form (:alternatives ...). Here we try to load each
       of the alternatives in order until one is loaded successfully. If
       none of the alternatives are loaded we get an error.

    d) A pair of the form (:framework "name"). CFFI will try to load the
       "name" framework, looking at the directories in
       cffi:*darwin-framework-directories* which is similar to
       cffi:*foreign-library-directories*. This list contains the
       following paths by default:

         1. ~/Library/Frameworks
         2. /Library/Frameworks
         3. /System/Library/Frameworks

       Obviously, the user can push more paths into this list.


There are some functions that I'm not sure are worth exporting:
find-foreign-library, find-and-load-foreign-library and
find-darwin-framework. Also, maybe a functional interface to
use-foreign-library could be useful?

Comments?



[1] We'll be removing :cffi/no-foreign-funcall, and pushing
    cffi-features:foreign-funcall instead. Also, we provide
    others like cffi-features:{windows,unix,darwin,ppc32,x86}
    so that users can rely on these across different lisps.

-- 
Luís Oliveira
luismbo (@) gmail (.) com
Equipa Portuguesa do Translation Project
http://www.iro.umontreal.ca/translation/registry.cgi?team=pt




More information about the cffi-devel mailing list