- To use LOAD-SHARED-OBJECT, at the Unix command line do this:
- 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.
-"
- (ensure-runtime-symbol-table-opened)
- ;; Note: We use RTLD-GLOBAL so that it can find all the symbols
- ;; previously loaded. We use RTLD-NOW so that dlopen() will fail if
- ;; not all symbols are defined.
- (let* ((real-file (or (unix-namestring file) file))
- (sap (dlopen real-file (logior rtld-now rtld-global))))
- (if (zerop (sap-int sap))
- (error "can't open object ~S: ~S" real-file (dlerror))
- (pushnew sap *handles-from-dlopen* :test #'sap=)))
- (values))
-
- (defun get-dynamic-foreign-symbol-address (symbol)
- (ensure-runtime-symbol-table-opened)
- ;; Find the symbol in any of the loaded object files. Search in
- ;; reverse order of loading, so that later loadings take precedence.
- ;;
- ;; FIXME: The way that we use PUSHNEW SAP in LOAD-SHARED-OBJECT means
- ;; that the list isn't guaranteed to be in reverse order of loading,
- ;; at least not if a file is loaded more than once. Is this the
- ;; right thing? (In what cases does it matter?)
- (dolist (handle (reverse *handles-from-dlopen*))
- ;; KLUDGE: We implicitly exclude the possibility that the variable
- ;; could actually be NULL, but the man page for dlsym(3)
- ;; recommends doing a more careful test. -- WHN 20000825
- (let ((possible-result (sap-int (dlsym handle symbol))))
- (unless (zerop possible-result)
- (return possible-result)))))
-
- )) ; PROGN, MACROLET