Hi,
I have:
(defun load-and-open-module (pathname) (let ((lib (cffi:load-foreign-library pathname))) (if lib (progn (format t "~%LOAD-AND-OPEN-MODULE: ~s LOADED." lib) (let ((handle (cffi:foreign-funcall `("open" :library ,lib) :pointer))) ;; <<--- Here's the challenge ... (if (not (eql handle (cffi:null-pointer))) (let ((module (make-instance 'pib-module :lib (c-in lib) :handle (c-in handle)))) (format t "~%LOAD-AND-OPEN-MODULE: module = ~s." module) module) nil) nil)))))
The marked line should load the "open" function in the just loaded foreign lib. As I intend to load multiple so-called modules where each module has an "open" function I /think/ I need to say which open() function to call (the loaded libs are C DLLs, mostly).
How do I name a certain foreign lib in the call to foreign-funcall when the library given is not evaluated ?
Thanks for any hints!
Cheers Frank
Frank Goenninger frgo@me.com writes:
The marked line should load the "open" function in the just loaded foreign lib. As I intend to load multiple so-called modules where each module has an "open" function I /think/ I need to say which open() function to call (the loaded libs are C DLLs, mostly).
How do I name a certain foreign lib in the call to foreign-funcall when the library given is not evaluated ?
Many CFFI backends have CFFI-FEATURES:FLAT-NAMESPACE, which you can (or can't) see in *features*. If you see it present after loading CFFI in your CL implementation, it means that underlying /native/ FFI is unable to work with multiple functions having the same name in different modules. If there is no CFFI-FEATURES:FLAT-NAMESPACE in *FEATURES*, you can use something like (CFFI:FOREIGN-FUNCALL ("open" :library my-module)), but it's fantastically unportable, and you'll have to DEFINE-FOREIGN-LIBRARY for each module in use.
Fortunately, CFFI:FOREIGN-FUNCALL-POINTER is widely available, so you may solve it the following way:
* define foreign interface to dlopen [or LoadLibrary] and dlsym [or GetProcAddress]
* load your module by calling dlopen [or LoadLibrary]
* call dlsym(<your-module-handle>,"open") [or GetProcAddress]
* dlsym/GetProcAddress returns a pointer to function, which you may call with CFFI:FOREIGN-FUNCALL-POINTER.