You're probably already familiar with the legacy FFI using defentry, as
I think axiom uses this already. This is a bit slow, but functional.
I've designed a new one with the goal of accessing shared libraries from
within GCL given its unique (it appears) ability to unexec a running
image, and reexec later, possibly on a different machine. A shared
library link therefore needs to be remembered in the image, together
with all code pointer locations which must be reset on image startup.
The following is implemented in the 2.7.0 tree, but can be backported
rather easily if you need it.
There is a :lib package:
(do-external-symbols (s :lib) (print s))
each external symbol of which tracks a live shared library binding, and
which also names another package with the dynamically linked symbols in
COMPILER>(do-external-symbols (s 'lib:|libm|) (print s))
One limitation at present is that the function cannot be run when
interpreted, i.e. must be compiled. I'll try to find time to fix this:
(compile '|libcblas|:|cblas_ddot| )
;; Compiling /tmp/gazonk_21018_0.lsp.
;; End of Pass 1.
;; End of Pass 2.
;; OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3, (Debug quality ignored)
;; Finished compiling /tmp/gazonk_21018_0.o.
;; Loading /tmp/gazonk_21018_0.o
start address -T 0xb66b50 ;; Finished loading /tmp/gazonk_21018_0.o
The function can now be used as any other function:
(setq a (make-array 10 :element-type 'long-float :static t
:initial-contents '(1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0)))
#(1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0)
(|libcblas|:|cblas_ddot| 10 a 1 a 1)
When the image is saved and restarted, the linking pointer is
GCL (GNU Common Lisp) NIL.NIL.NIL CLtL1 May 25 2012 14:58:14
Source License: LGPL(gcl,gmp,pargcl), GPL(unexec,bfd,xgcl)
Binary License: GPL due to GPL'ed components: (XGCL READLINE UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter
Use (help) to get some basic information on how to use GCL.
Temporary directory for compiler files set to /tmp/
COMPILER>(|libcblas|:|cblas_ddot| 10 a 1 a 1)
On Debian based systems, such blas calls automatically proceed to
optimized atlas calls (when installed) making use of specialized vector
One thing that should be kept in mind when using blas/lapack/atlas is
that the latter can call malloc under certain circumstances. I wish
these libraries had some means to toggle allocation on the stack, but
they don't, or at least didn't last time I looked. This means that if
you pass arrays allocated in relocatable memory, the result could be
corrupted if a gc is triggered. We wrote gmp wrappers to handle a
similar situation. But for a generic interface, this is impossible, so
arrays should be allocated in contiguous block memory to be safe,
i.e. using the :static t keywords in make-array. It is somewhat of a
pity, as such memory is slower to GC.
If you have any questions, please feel free.
Camm Maguire camm@magu... ==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah