123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- @node Dynamic loading of C modules
- @section Dynamic loading of C modules
- @cindex C dynamic loading
- @cindex C shared objects
- @stindex load-dynamic-externals
- External code can be loaded into a running Scheme48 on most Unices and
- on Windows. Such external code must be stored in shared objects; see
- below on details of the C side. The relevant Scheme procedures are
- available in the @code{load-dynamic-externals} structure:
- @deffn procedure load-dynamic-externals filename add-file-type? reload-on-repeat? reload-on-resume? @returns{} dynamic-externals
- @deffnx procedure import-dynamic-externals filename @returns dynamic-externals
- @deffnx procedure unload-dynamic-externals dynamic-externals @returns{} unspecified
- @code{Load-dynamic-external} loads a shared object from
- @var{filename}, with an appropriate file type appended if
- @var{add-file-type?} is true (@code{.so} on Unix and @code{.dll} on
- Windows), and returns a @dfn{dynamic externals} object representing
- the loaded shared object. If the shared object was already loaded,
- then if @var{reload-on-repeat?} is true, it is reloaded; otherwise,
- the @code{load-dynamic-externals} call has no effect. If the dynamic
- externals descriptor is stored in a dumped heap image, when that heap
- image is resumed, if @code{reload-on-resume?} is true, the shared
- object corresponding with that dynamic external descriptor is
- reloaded. @code{Unload-dynamic-externals} unloads the given dynamic
- externals object.
- @code{Import-dynamic-externals} is a convenient wrapper for the common
- case of @code{load-dynamic-externals}; it is equivalent to
- @code{(load-dynamic-externals #t #f #t)}, @ie{} it will append a file
- type, it will not reload the shared object if it was already loaded,
- and the shared object will be loaded if part of a resumed heap image.
- @end deffn
- @deffn procedure reload-dynamic-externals filename @returns{} unspecified
- Reloads the shared object named by @var{filename}. This is intended
- as an interactive utility, which is why it accepts the filename of the
- shared object and not a dynamic externals descriptor.
- @end deffn
- Shared objects intended to be loaded into Scheme48 must define two
- functions:
- @deftypefn {C function} void s48_on_load (void)
- @deftypefnx {C function} void s48_on_reload (void)
- @code{s48_on_load} is called when the shared object is initially
- loaded by Scheme48. It typically consists of a number of invocations
- of @code{S48_EXPORT_FUNCTION} to make C functions available to
- Scheme48 code. @code{s48_on_reload} is called when the shared object
- is reloaded after it has been initially loaded once; it typically just
- calls @code{s48_on_load}, but it may perform other reinitializations.
- @end deftypefn
- On Linux, the following commands compile the C source file
- @file{foo.c} into a shared object @file{foo.so} that can be loaded
- dynamically by Scheme48:
- @example
- % gcc -c -o foo.o foo.c
- % ld -shared -o foo.so foo.o@end example
- @subsection Old dynamic loading interface
- The old @code{dynamic-externals} structures, which exported
- @code{dynamic-load}, @code{get-external}, @code{lookup-external},
- @code{lookup-all-externals}, @code{external?}, @code{external-name},
- @code{external-value}, and @code{call-external}, is still supported,
- but it will not work on Windows, its use is deprecated, and it is
- likely to vanish in a future release. The old documentation is
- preserved to aid updating of old code:
- @stindex dynamic-externals
- On architectures that support it, external code can be loaded into a
- running Scheme48 process, and C object file bindings can be accessed
- at runtime & their values called. These Scheme procedures are exported
- by the structure @code{dynamic-externals}.
- In some Unices, retrieving a value from the current process may require
- a non-trivial amount of computation. We recommend that a dynamically
- loaded file contain a single initialization function that creates
- shared bindings for the values exported by the file.
- @deffn {Scheme procedure} dynamic-load string @returns{} unspecified
- Loads the filename named by @var{string} into the current process.
- An exception is raised if the file cannot be found or if dynamic
- loading is not supported by the host operating system. The file must
- have been compiled & linked appropriately. For Linux, for example,
- the following commands compile @file{foo.c} into a file @file{foo.so}
- that can be loaded dynamically:
- @example
- % gcc -c -o foo.o foo.c
- % ld -shared -o foo.so foo.o@end example
- @end deffn
- @deffn {Scheme procedure} get-external string @returns{} external
- @deffnx {Scheme procedure} external? object @returns{} boolean
- @deffnx {Scheme procedure} external-name external @returns{} string
- @deffnx {Scheme procedure} external-value external @returns{} byte-vector
- These procedures access external values bound in the current process.
- @code{Get-external} returns a @dfn{external} object that contains the
- value of the C binding with the name @var{string}. It signals a
- warning if there is no such binding in the current process.
- @code{External?} is the disjoint type predicate for externals, and
- @code{external-name} & @code{external-value} return the name & value of
- an external. The value is represented as a @embedref{Bitwise
- manipulation,byte vector} of length four on 32-bit architectures. The
- value is that of the C binding from when @code{get-external} (or
- @code{lookup-external}, as described below) was called.
- @end deffn
- @deffn {Scheme procedure} lookup-external external @returns{} boolean
- @deffnx {Scheme procedure} lookup-all-externals @returns{} boolean
- @code{Lookup-external} updates the value of @var{external} by looking
- up its binding in the current process. It returns @code{#t} if the
- external is bound and @code{#f} if not. @code{Lookup-all-externals}
- calls @code{lookup-external} on all externals in the current Scheme48
- image. It returns @code{#t} if all were bound and @code{#f} if there
- was at least one unbound external.
- @end deffn
- @deffn {Scheme procedure} call-external external argument @dots{} @returns{} value
- Calls the C function pointed to by @var{external} with the given
- arguments, and returns the value that the C function returned. This
- is like @code{call-imported-binding} and @code{call-external-value}
- except that the function argument is represented as an external, not as
- an imported binding or byte vector containing a pointer. For more
- details, @pxref{Calling C functions from Scheme}.
- @end deffn
|