Jeremy Smith jeremy@decompiler.org writes:
I'm posting this to the CFFI discussion group, I previously posted it to the Lisp Application Builder list.
(Sorry for the delay in approving your message; the list gets so much spam I don't check it all that often.)
What I'm getting to is, I read on comp.lang.lisp that the CFFI-based SDL module does not work on Windows 98 under Clisp. I just tested it on my Windows 98 laptop (P166 :-) and it says the same thing. "FFI: FOREIGN-LIBRARY-FUNCTION: No dynamic object named 'SDL_Init' in library :DEFAULT"
My first guess is that you are using an older version of CLISP that is technically unsupported by CFFI. What CLISP version are you using, and do the SDL bindings work if you upgrade to the latest release?
IIRC, several releases ago, a feature was added to CLISP to look for foreign symbols globally when the library is :DEFAULT, instead of only in the C library. Perhaps this is not working on Win9x... does this work under NT/XP/whatever?
I did a little bit of detective work:
Clisp's top-level view shows the scope, at the time of the above error as (from src/cffi-clisp.lisp):
`(funcall (load-time-value (ffi::foreign-library-function ,name (ffi::foreign-library :default) nil (ffi:parse-c-type ',ctype))) ,@fargs))))
The FFI documentation says nothing about a load-time-value, and ffi::foreign-library is not mentioned either. Strange!
In the CFFI design, the lowest level operator for calling a foreign function is CFFI:FOREIGN-FUNCALL, which can be used for one-shot calls to any C function with argument types known at compile-time:
(foreign-funcall "puts" :string "Hello, world!" :void)
The DEFCFUN macro (in almost all Lisp implementations) expands into a normal Lisp DEFUN that uses FOREIGN-FUNCALL to effect the actual foreign function call.
The LOAD-TIME-VALUE in FOREIGN-FUNCALL is there to avoid resolving the foreign function each time it is called; instead it is done once when the fasl file is loaded.
(ffi:def-call-out SDL_Init (:name "SDL_Init") (:library "sdl.dll") (:return-type ffi:int) (:arguments (flags Uint32)))
If this works with (:library :default) using the CLISP FFI (as I understand it should, if sdl.dll has been loaded), then I would expect it to work in CFFI as well.
James