| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each dynamically loadable XEmacs extension (hereafter referred to as a module) has a certain compulsory format, and must contain several pieces of information and several mandatory functions. This chapter describes the basic layout of a module, and provides a very simple sample. The source for this sample can be found in the file `modules/simple/sample.c' in the main XEmacs source code tree.
| 2.1 Required Header File | Always include <emodules.h> | |
| 2.2 Required Functions | Functions you must always provide | |
| 2.3 Required Variables | Variables whose values you must provide | |
| 2.4 Loading other Modules | How to load dependent modules |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Every module must include the file `<emodules.h>'. This will include several other XEmacs internal header files, and will set up certain vital macros. One of the most important files included by `emodules.h' is the generated `config.h' file, which contains all of the required system abstraction macros and definitions. Most modules will probably require some pre-processor conditionals based on constants defined in `config.h'. Please read that file to familiarize yourself with the macros defined there.
Depending on exactly what your module will be doing, you will probably
need to include one or more of the XEmacs internal header files. When
you #include <emodules.h>, you will get a few of the most important
XEmacs header files included automatically for you. The files included
are:
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Every module requires several initialization functions. It is the
responsibility of these functions to load in any dependent modules, and to
declare all variables and functions which are to be made visible to the
XEmacs Lisp reader. Each of these functions performs a very specific
task, and they are executed in the correct order by XEmacs. All of
these functions are void functions which take no arguments.
Here, briefly, are the required module functions. Note that the actual
function names do not end with the string _module, but rather
they end with the abbreviated module name by which the module is known.
More on the module name and its importance later. Just bear in mind
that the text _module in the functions below is simply a
place-holder, not an actual function name.
syms_of_module
DEFUN(). Note that only functions are declared here, using
the DEFSUBR() macro. No variables are declared.
vars_of_module
DEFVAR_LISP(), DEFVAR_BOOL() etc, and its purpose is to
declare and initialize all and any variables that your module defines.
They syntax for declaring variables is identical to the syntax used for
all internal XEmacs source code. If the module is intended to be
usable statically linked into XEmacs, the actions of this function are
severely restricted. See section `General Coding Rules' in XEmacs Internals Manual. Also see the comments in
`src/emacs.c' (main_1). Modules which perform
initializations not permitted by these rules will probably work, but
dual-use (dynamic loading and static linking) modules will require very
careful, and possibly fragile, coding.
modules_of_module
docs_of_module
ellcc when the module
initialization code is produced. It is required to document all
functions and variables declared in your module.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Not only does a module need to declare the initialization functions
mentioned above, it is also required to provide certain variables which
the module loading code searches for in order to determine the viability
of a module. You are not required to provide these variables in
your source files. They are automatically set up in the module
initialization file by the ellcc compiler. These variables are
discussed here simply for the sake of completeness.
emodules_compiler
long, and is used to indicate the
version of the XEmacs loading technology that was used to produce the
module being loaded. This version number is completely unrelated to
the XEmacs version number, as a given module may quite well work
regardless of the version of XEmacs that was installed at the time the
module was created.
The XEmacs modules version is used to differentiate between major changes in the module loading technology, not versions of XEmacs.
emodules_name
syms_of_, vars_of_, modules_of_ and
docs_of_ to form the actual function names that the module
loading code looks for when loading a module.
This variable is set by the --mod-name argument to ellcc.
emodules_version
load-module for more details. This variable is set by the
--mod-version argument to ellcc.
emodules_title
--mod-title argument to ellcc.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
During the loading of a module, it is the responsibility of the function
modules_of_module to load in any modules which the current module
depends on. If the module is stand-alone, and does not depend on other
modules, then this function can be left empty or even undeclared.
However, if it does have dependencies, it must call
emodules_load:
int emodules_load (const char *module,
const char *modname,
const char *modver)
|
The first argument module is the name of the actual shared object
or DLL. You can omit the `.so', `.ell' or `.dll'
extension of you wish. If you do not specify an absolute path name,
then the same rules as apply to loading Lisp modules are applied when
searching for the module. If the module cannot be found in any of the
standard places, and an absolute path name was not specified,
emodules_load will signal an error and loading of the module
will stop.
The second argument (modname) is the module name to load, and
must match the contents of the variable emodule_name in the
module to be loaded. A mis-match will cause the module load to fail. If
this parameter is NULL or empty, then no checks are performed
against the target module's emodule_name variable.
The last argument, modver, is the desired version of the module
to load, and is compared to the target module's
emodule_version value. If this parameter is not NULL
or empty, and the match fails, then the load of the module will fail.
emodules_load can be called recursively. If, at any point
during the loading of modules a failure is encountered, then all modules
that were loaded since the top level call to emodules_load
will be unloaded. This means that if any child modules fail to load,
then their parents will also fail to load. This does not include
previous successful calls to emodules_load at the top level.
Warning: Modules are not loaded with the
RTLD_GLOBAL flag. The practical upshot is that individual
modules do not have access to each other's C symbols. One module cannot
make a C function call to a function defined in another module, nor can
it read or set a C variable in another module. All interaction between
modules must, therefore, take place at the Lisp level. This is by
design. Other projects have attempted to use RTLD_GLOBAL, only
to find that spurious symbol name clashes were the result. Helper
functions often have simple names, increasing the probability of such a
clash. If you really need to share symbols between modules, create a
shared library containing those symbols, and link your modules with
that library. Otherwise, interactions between modules must take place
via Lisp function calls and Lisp variables accesses.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |