Darwin/MacOS X shared libraries and extensions differ significantly from Linux shared libraries. The initial release of OpenMCL for Darwin doesn't support loading and unloading shared libraries. When that functionality is added in a later release, the details will likely differ somewhat from those described below.
In OpenMCL 0.10 under Darwin:
the functions OPEN-SHARED-LIBRARY and CLOSE-SHARED-LIBRARY are undefined.
the EXTERNAL macro resolves the symbol's address but doesn't try to identify the containing library. (Note that function names that are visible to C functions have leading underscores under Darwin.)
OpenMCL provides facilities to open and close shared libraries.
"Opening" a shared library maps the library's code and data into OpenMCL's address space and makes its exported symbols accessible to OpenMCL.
"Closing" a shared library unmaps the library's code and data and removes the library's symbols from the global namespace.
A small number of shared libraries (including libc, libm, libdl) are opened by the lisp kernel and can't be closed.
OpenMCL uses data structures of type EXTERNAL-ENTRY-POINT
to map a foreign function name (string) to that foreign function's
current address. (A function's address may vary from
session to session as different versions of shared libraries may
load at different addresses; it may vary within a session for
similar reasons.)
An EXTERNAL-ENTRY-POINT
whose address is known is said
to be resolved. When an external entry point is resolved,
the shared library which defines that entry point is noted; when
a shared library is closed, the entry points that it defines are
made unresolved. An EXTERNAL-ENTRY-POINT
must be
in the resolved state in order to be FF-CALL
ed; calling
an unresolved entry point causes a "last chance" attempt to resolve
it. Attempting to resolve an entrypoint that was defined in a
closed library will cause an attempt to reopen that library.
OpenMCL keeps track of all libraries that have been opened in a lisp session. When a saved application is first started, an attempt is made to reopen all libraries that were open when the image was saved, and an attempt is made to resolve all entrypoints that had been referenced when the image was saved. Either of these attempts can fail "quietly", leaving some entry points in an unresolved state.
Linux shared libraries can be referred to either by a string
which describes their full pathname or by their soname,
a shorter string that can be defined when the library is
created. The dynamic linker mechanisms used in Linux make it
possible (through a series of filesystem links and other means)
to refer to a library via several names; the library's
soname
is often the most appropriate identifier.
soname
s are often less version-specific than
other names for libraries; a program that refers to a
library by the name "libc.so.6" is more portable than one
which refers to "libc-2.1.3.so" or to "libc-2.2.3.so", even
though the latter two names might each be platform-specific
aliases of the first.
All of the global symbols described below are exported from the CCL package.
Syntax | open-shared-library name |
Description |
If the library denoted by name can be loaded by the
operating system, returns an object of type SHLIB that describes
the library; if the library is already open, increments a reference
count. If the library can't be loaded, signals a
SIMPLE-ERROR which contains an often cryptic
message from the operating system.
|
Arguments |
|
Syntax | close-shared-library shlib &key (completely t) |
Description |
Decrements the shared library's reference count until
it becomes 0 (if completely is T) or by 1
otherwise. If the reference count becomes 0, frees
memory resources consumed by the library and causes
any EXTERNAL-ENTRY-POINT s known to be
defined in the library to become unresolved.
|
Arguments |
|
Syntax | external name |
Description |
Finds or creates an EXTERNAL-ENTRY-POINT which
maintains the address of specified foreign symbol. Tries
to resolve the entry point and identify the containing
library.
|
Arguments |
|
;;; Try to do something simple. ? (open-shared-library "libgtk.so") > Error: Error opening shared library "libgtk.so": /usr/lib/libgtk.so: undefined symbol: gdk_threads_mutex > While executing: OPEN-SHARED-LIBRARY ;;; Grovel around, curse, and try to find out where "gdk_threads_mutex" ;;; might be defined. Then try again: ? (open-shared-library "libgdk.so") #<SHLIB libgdk.so #x3046DBB6> ? (open-shared-library "libgtk.so") #<SHLIB libgtk.so #x3046DC86> ;;; Reference an external symbol defined in one of those libraries. ? (external "gtk_main") #<EXTERNAL-ENTRY-POINT "gtk_main" (#x012C3004) libgtk.so #x3046FE46> ;;; Close those libraries. ? (close-shared-library "libgtk.so") T ? (close-shared-library "libgdk.so") T ;;; Reference the external symbol again. ? (external "gtk_main") #<EXTERNAL-ENTRY-POINT "gtk_main" {unresolved} libgtk.so #x3046FE46>
ldd
and
ldconfig
programs.