Next: Module Functions, Up: Writing Dynamic Modules
Begin your module by including the header file emacs-module.h and defining the GPL compatibility symbol:
#include <emacs-module.h> int plugin_is_GPL_compatible;
The emacs-module.h file is installed into your system's include tree as part of the Emacs installation. Alternatively, you can find it in the Emacs source tree.
Next, write an initialization function for the module.
Emacs calls this function when it loads a module. If a module does not export a function named
emacs_module_init
, trying to load the module will signal an error. The initialization function should return zero if the initialization succeeds, non-zero otherwise. In the latter case, Emacs will signal an error, and the loading of the module will fail. If the user presses C-g during the initialization, Emacs ignores the return value of the initialization function and quits (see Quitting). (If needed, you can catch user quitting inside the initialization function, see should_quit.)The argument runtime is a pointer to a C
struct
that includes 2 public fields:size
, which provides the size of the structure in bytes; andget_environment
, which provides a pointer to a function that allows the module initialization function access to the Emacs environment object and its interfaces.The initialization function should perform whatever initialization is required for the module. In addition, it can perform the following tasks:
- Compatibility verification
- A module can verify that the Emacs executable which loads the module is compatible with the module, by comparing the
size
member of the runtime structure with the value compiled into the module:int emacs_module_init (struct emacs_runtime *ert) { if (ert->size < sizeof (*ert)) return 1; }If the size of the runtime object passed to the module is smaller than what it expects, it means the module was compiled for an Emacs version newer (later) than the one which attempts to load it, i.e. the module might be incompatible with the Emacs binary.
In addition, a module can verify the compatibility of the module API with what the module expects. The following sample code assumes it is part of the
emacs_module_init
function shown above:emacs_env *env = ert->get_environment (ert); if (env->size < sizeof (*env)) return 2;This calls the
get_environment
function using the pointer provided in theruntime
structure to retrieve a pointer to the API's environment, a Cstruct
which also has asize
field holding the size of the structure in bytes.Finally, you can write a module that will work with older versions of Emacs, by comparing the size of the environment passed by Emacs with known sizes, like this:
emacs_env *env = ert->get_environment (ert); if (env->size >= sizeof (struct emacs_env_26)) emacs_version = 26; /* Emacs 26 or later. */ else if (env->size >= sizeof (struct emacs_env_25)) emacs_version = 25; else return 2; /* Unknown or unsupported version. */This works because later Emacs versions always add members to the environment, never remove any members, so the size can only grow with new Emacs releases. Given the version of Emacs, the module can use only the parts of the module API that existed in that version, since those parts are identical in later versions.
We recommend that modules always perform the compatibility verification, unless they do their job entirely in the initialization function, and don't access any Lisp objects or use any Emacs functions accessible through the environment structure.
- Binding module functions to Lisp symbols
- This gives the module functions names so that Lisp code could call it by that name. We describe how to do this in Module Functions below.