[Ecls-list] Status of dynamic FFI

Juan Jose Garcia Ripoll lisp at arrakis.es
Mon Oct 17 06:03:26 UTC 2005


[Courtesy copy of an item to be posted at ECL's RSS]

ECL's unstable version (in CVS) now contains means both to call C
functions and to export functions to the C world (callbacks).
Furthermore, this project, initiated by M. Goffioul, has led to an
implementation that, at least on the Intel platform, does not rely on
the C compiler, but on assembler code generated run time. We hope to
port this to the remaining architectures: PPC, Sparc, x86_64

If you want to test it, save the code below in a file called
"example.lsp" and load it in the interpreter (if on
x86/Windows,Linux,FreeBSD) or compile it and load it (if on other
platforms).

The output should look as follows: the first column is the input value,
the second and fourth column are the output of either a callback or a C
function (in this case "sin"). Other columns are provided to compare
accuracy of the result.

Value      1+ (cback) lisp       sin(cfun) lisp
=====================================================
         0        1.0        1.0        0.0        0.0
         1        2.0        2.0 .841470985 0.84147096
         2        3.0        3.0 .909297427  0.9092974
         3        4.0        4.0 .141120008    0.14112
         4        5.0        5.0 -0.7568025 -0.7568025
         5        6.0        6.0 -.95892427 -0.9589243
         6        7.0        7.0 -0.2794155 -0.2794155
         7        8.0        8.0 .656986599  0.6569866
         8        9.0        9.0 .989358247 0.98935825
         9       10.0       10.0 .412118485  0.4121185


;; Notice that the following example will work on all platforms if
compiled
;; as in
;;	(COMPILE-FILE "example.lisp")
;;	(LOAD-FILE "example")
;;
;; However, on the x86 platform (i.e. Intel running Linux, FreeBSD,
Windows,
;; etc on 32 bit modes), this example also works when loaded from the
;; interpreter. In this case, assembly code is built at run-time and
there
;; is no need to have a C compiler around. Ports to other architectures
are
;; being developed and any kind of help is welcome.
;;

;;
;; This is a "callback", i.e. a function that can be called from the C
world.
;; We can retreive a UFFI pointer to this function using #'FFI:CALLBACK,
as
;; shown below.
;;
(ffi:defcallback increment :double ((x :double))
   (1+ x)
)

;;
;; This is a foreign function, i.e. a C function that can be called from
the
;; lisp world. Here we do not need to handle pointers: a lisp function
called
;; C-SIN is created that does the job of translating arguments for us.
The
;; syntax here is pure UFFI.
;;
(ffi:def-function ("sin" C-sin)
((x :double)) :returning :double :module :default)


(format t "Value      1+ (cback) lisp       sin(cfun) lisp      ~%")
(format t "=====================================================~%")

(dotimes (i 10)
  (format t "~10D ~10f ~10f ~10f ~10f~%"
	  i
	  (si::call-cfun (ffi:callback 'increment) :double '(:double) (list i))
	  (1+ i)
	  (C-sin i)
	  (sin i)))







More information about the ecl-devel mailing list