- echo 'int summish(int x, int y) { return 1 + x + y; }' > /tmp/ffi-test.c
- make /tmp/ffi-test.o # i.e. cc -c -o /tmp/ffi-test.o /tmp/ffi-test.c
- ld -shared -o /tmp/ffi-test.so /tmp/ffi-test.o
-
-Then in SBCL do this:
-
- (load-shared-object \"/tmp/ffi-test.so\")
- (define-alien-routine summish int (x int) (y int))
-
-Now running (summish 10 20) should return 31."
- (let* ((real-file (or (unix-namestring file) file))
- (sap (dlopen-or-lose real-file))
- (obj (make-shared-object :file real-file :sap sap)))
- (unless (member sap *shared-objects*
- :test #'sap= :key #'shared-object-sap)
- (setf *shared-objects* (append *shared-objects* (list obj))))
- (pathname real-file)))
+(defun load-shared-object (file)
+ "Load a shared library/dynamic shared object file/general dlopenable
+alien container, such as a .so on an ELF platform.
+
+Reloading the same shared object will replace the old definitions; if
+a symbol was previously referenced thru the object and is not present
+in the reloaded version an error will be signalled. Sameness is
+determined using the library filename. Reloading may not work as
+expected if user or library-code has called dlopen on FILE.
+
+References to foreign symbols in loaded shared objects do not survive
+intact through SB-EXT:SAVE-LISP-AND die on all platforms. See
+SB-EXT:SAVE-LISP-AND-DIE for details."
+ (sb!thread:with-mutex (*foreign-lock*)
+ (let* ((filename (or (unix-namestring file) file))
+ (old (find filename *shared-objects* :key #'shared-object-file :test #'equal))
+ (obj (or old (make-shared-object :file filename))))
+ (dlopen-or-lose obj)
+ (setf *shared-objects* (append (remove obj *shared-objects*)
+ (list obj)))
+ #!+linkage-table
+ (when (or old (undefined-foreign-symbols))
+ (update-linkage-table))
+ (pathname filename))))