[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Anatomy of a Module

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] [ ? ]

2.1 Required Header File

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:

`lisp.h'
This file contains most of the macros required for declaring Lisp object types, macros for accessing Lisp objects, and global variable declarations.

`sysdep.h'
All system dependent declarations and abstraction macros live here. You should never call low level system functions directly. Rather, you should use the abstraction macros provided in this header file.

`window.h'
This header file defines the window structures and Lisp types, and provides functions and macros for manipulating multiple XEmacs windows.

`buffer.h'
All macros and function declarations for manipulating internal and user visible buffers appear in this file.

`insdel.h'
This header provides the information required for performing text insertion and deletion.

`frame.h'
Provides the required structure, macro and function definitions for manipulating XEmacs frames.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 Required Functions

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
This required function is responsible for introducing to the Lisp reader all functions that you have defined in your module using DEFUN(). Note that only functions are declared here, using the DEFSUBR() macro. No variables are declared.

vars_of_module
This required function contains calls to macros such as 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
This optional function should be used to load in any modules which your module depends on. The XEmacs module loading code makes sure that the same module is not loaded twice, so several modules can safely call the module load function for the same module. Only one copy of each module (at a given version) will ever be loaded.

docs_of_module
This is a required function, but not one which you need ever write. This function is created automatically by 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] [ ? ]

2.3 Required Variables

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
This is a variable of type 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
This is a short (typically 10 characters or less) name for the module, and it is used as a suffix for all of the required functions. This is also the name by which the module is recognized when loading dependent modules. The name does not necessarily have to be the same as the physical file name, although keeping the two names in sync is a pretty good idea. The name must not be empty, and it must be a valid part of a C function name. The value of this variable is appended to the function names 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
This string variable is used to load specific versions of a module. Rarely will two or more versions of a module be left lying around, but just in case this does happen, this variable can be used to control exactly which module should be loaded. See the Lisp function load-module for more details. This variable is set by the --mod-version argument to ellcc.

emodules_title
This is a string which describes the module, and can contain spaces or other special characters. It is used solely for descriptive purposes, and does not affect the loading of the module. The value is set by the --mod-title argument to ellcc.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.4 Loading other Modules

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] [ ? ]

This document was generated by XEmacs Webmaster on August, 3 2012 using texi2html