Frank Goenninger | 5 Dec 00:21 2011

Dynamically call a certain function in a lib

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
(Continue reading)

Anton Kovalenko | 5 Dec 00:42 2011

Re: Dynamically call a certain function in a lib

Frank Goenninger <frgo <at> 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
(Continue reading)


Gmane