Hi,
I have committed a rather simple implementation of callbacks for ECL, with a syntax resembling that of CFFI.
Unfortunately, and in contrast to ECL's SI::CALL-CFUN this implementation does rely on the compiler. I thought about trying something different but that would be far too difficult, as it would involve dynamically creating assembly code, plus allocating regions of executable memory, etc, etc.
Both the implementation of callbacks and of dynamically generated calls to C functions (SI::CALL-CFUN) are experimental code. Critics and suggestions are welcome.
Enjoy,
Juanjo
An example file: foo.lsp
(ffi:defcallback foo :int ((a :int)) (1+ a) )
(dotimes (i 10) (print (list i (si::call-cfun (ffi:callback 'foo) :int '(:int) (list i)))))
Resulting session:
~/src/ecls-new/build$ ecl ECL (Embeddable Common-Lisp) 0.9g Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya Copyright (C) 1993 Giuseppe Attardi Copyright (C) 2000 Juan J. Garcia-Ripoll ECL is free software, and you are welcome to redistribute it under certain conditions; see file 'Copyright' for details. Type :h for Help. Top level.
(compile-file "foo")
;;; Loading #P"/home/jlr/lib/ecl/cmp.fas" ;;; Loading #P"/home/jlr/lib/ecl/sysfun.lsp" ;;; Compiling foo. ;;; End of Pass 1. ;;; Emitting code for FOO. ;;; Note: Emiting FUNCALL for FFI:CALLBACK ;;; Calling the C compiler... ;;; Note: ;;; Invoking external command: gcc -I../include -g -O2 -fPIC -fstrict-aliasing -Dlinux -O "-I/home/jlr/lib/ecl//h" -w -c "foo.c" -o "foo.o"
;;; Note: ;;; Invoking external command: gcc -o "foo.fas" -L"/home/jlr/lib/ecl/" "foo.o" -Wl,--rpath,/home/jlr/lib/ecl/ -shared -lecl -ldl -lm -lgmp
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 ;;; Finished compiling foo. #P"/home/jlr/src/ecls-new/build/foo.fas" NIL NIL
(load "foo")
;;; Loading #P"foo.fas"
(0 1) (1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8) (8 9) (9 10) #P"foo.fas"
On 11/out/2005, at 10:25, Juan Jose Garcia Ripoll wrote:
Both the implementation of callbacks and of dynamically generated calls to C functions (SI::CALL-CFUN) are experimental code. Critics and suggestions are welcome.
I plan to update cffi-ecl.lisp soon since it's the backend that is lacking the most features, the only reason I haven't yet is because ECL doesn't like some of the code in cffi-luis/types.lisp (which I plan to rewrite). I won't be able to until later this month though.
So, I read about the new SI::CALL-CFUN in ECL's mailing list, should we use that in CFFI's %foreign-funcall primitive? (Therefore in DEFCFUN too?)
Does that mean ECL's FFI:LOAD-FOREIGN-LIBRARY now supports non-constant arguments? (only if we use SI::CALL-CFUN I suppose).
On Tue, 2005-10-11 at 12:17 +0100, Luis Oliveira wrote:
I plan to update cffi-ecl.lisp soon since it's the backend that is lacking the most features, the only reason I haven't yet is because ECL doesn't like some of the code in cffi-luis/types.lisp (which I plan to rewrite). I won't be able to until later this month though.
Ok. If you run into troubles with ECL, please contact us at the mailing list.
So, I read about the new SI::CALL-CFUN in ECL's mailing list, should we use that in CFFI's %foreign-funcall primitive? (Therefore in DEFCFUN too?)
Yes, essentially si::call-cfun implements what CFFI's %foreign-funcall does. However, si::call-cfun can only handle a bunch of elementary types: :char, :int, :pointer-void, etc. So, some translation of the type names might be required. Eventually I can port some of CFFI's type names to ECL if needed. The change is rather simple.
Does that mean ECL's FFI:LOAD-FOREIGN-LIBRARY now supports non-constant arguments? (only if we use SI::CALL-CFUN I suppose).
Yes. But both si::call-cfun and the improved load-foreign-library only work in x86-32bit right now. I will be working on the ppc and x86-64 ports in the coming months.
Regards,
Juanjo