[cffi-devel] [PATCH] fix %load-foreign-library on cmucl

Stelian Ionescu stelian.ionescu-zeus at poste.it
Fri Dec 8 13:52:08 UTC 2006


On Fri, Dec 08, 2006 at 09:09:38AM +0000, Luís Oliveira wrote:
>On 12/6/06, Stelian Ionescu <stelian.ionescu-zeus at poste.it> wrote:
>
>(defun %load-foreign-library (name)
>  "Load the foreign library NAME."
>-  (sys::load-object-file name))
>+  (or (sys::load-object-file name)
>+      t))
>
>Hmm, that way %LOAD-FOREIGN-LIBRARY will never return NIL, even when
>loading the library really fails. We should be detecting if the
>foreign library is already loaded, and we should probably keep track
check this new patch

>of this in the portable side of things. That's needed for
I'm not sure this can be done reliably, imagine for instance that
someone may load libraries in their initialization file *before* loading
cffi which would lead to incongruities between the lisp implementation
and cffi; we should see first how many of the supported implementations
have a means to see which foreign libraries have been loaded. on CMUCL
there's SYS::*GLOBAL-TABLE*, on SBCL there's SB-ALIEN::*SHARED-OBJECTS*
but I don't know about the others

>UNLOAD-FOREIGN-LIBRARY too, it's in the TODO list I think.
>
>You're welcome to tackle that TODO item. :-)
I'll see what I can do

-- 
(sign :name "Stelian Ionescu" :aka "fe[nl]ix"
      :quote "Quidquid latine dictum sit, altum sonatur.")
-------------- next part --------------
--- old-cffi/src/cffi-cmucl.lisp	2006-12-08 14:34:28.000000000 +0100
+++ new-cffi/src/cffi-cmucl.lisp	2006-12-08 14:34:28.000000000 +0100
@@ -341,13 +341,33 @@
 
 (defun %load-foreign-library (name)
   "Load the foreign library NAME."
-  (sys::load-object-file name))
+  
+  ;; one some platforms SYS::LOAD-OBJECT-FILE signals an error when
+  ;; loading fails, but on others(Linux for instance) it returns
+  ;; two values: NIL and an error string
+  (handler-case
+      (multiple-value-bind (ret message)
+          (sys::load-object-file name)
+        (cond
+          ;; loading failed
+          ((stringp message) nil)
+          ;; the library was already loaded
+          ((null ret)        (values (rassoc name sys::*global-table*
+                                             :test #'string=)
+                                     :already-loaded))
+          ;; the library has been loaded, but since SYS::LOAD-OBJECT-FILE
+          ;; returns an alist of *all* loaded libraries along with their addresses
+          ;; we return only the handler associated with the library just loaded
+          (t                 (rassoc name ret :test #'string=))))
+    (error (err)
+      (declare (ignore err))
+      nil)))
 
 ;;; XXX: doesn't work on Darwin; does not check for errors. I suppose we'd
 ;;; want something like SBCL's dlclose-or-lose in foreign-load.lisp:66
 (defun %close-foreign-library (name)
   "Closes the foreign library NAME."
-  (let ((lib (find name sys::*global-table* :key #'cdr :test #'string=)))
+  (let ((lib (rassoc name sys::*global-table* :test #'string=)))
     (sys::dlclose (car lib))
     (setf (car lib) (sys:int-sap 0))))
 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20061208/ed014298/attachment.sig>


More information about the cffi-devel mailing list