|
External Development Guide: Adding System Routines |
|
LINKIMAGE can be used to make IDL load your system routines in a simple and efficient manner. However, it quickly becomes inconvenient if you are adding more than a few routines. Furthermore, the limitation that the LINKIMAGE call must happen before any code that calls it is compiled makes it difficult to use and complicates the process of redistributing your routines to others. IDL offers an alternative method of packaging your system routines, called Dynamically Loadable Modules (DLMs), that address these and other problems.
The IDL_SYSFUN_DEF2 structure, which is described in Registering Routines, contains all the information required by IDL for it to be able to compile calls to a given system routine and call it:
IDL does not require the actual code that implements the function until the routine is called: It is able to compile other routines and statements that reference it based only on its signature.
DLMs exploit this fact to load system routines on an "as needed" basis. The routines in a DLM are not loaded by IDL unless the user calls one of them. A DLM consists of two files:
DLMs are a powerful way to extend IDL's built in system routines. This form of packaging offers many advantages:
Use of sharable libraries in this manner has ample precedent in the computer industry. Most modern operating systems use loadable kernel modules to keep the kernel small while the functionality grows. The same technique is used in user programs in the form of sharable libraries, which allows unrelated programs to share code and memory space (e.g. a single copy of the C runtime library is used by all running programs on a given system).
IDL manages DLMs in the following manner:
After the current working directory, IDL searches !DLM_PATH for .dlm files and adds them to the table in the same manner. The default value of !DLM_PATH is the directory in the IDL distribution where the binary executables are kept. This default can be changed by defining the IDL_DLM_PATH preference (similarly to the way the IDL_PATH preference works with !PATH). This process happens once at startup, and never again. This means that IDL's knowledge of loadable modules is static and unchangeable once the session is underway. This is very different from the way !PATH works, and reflects the static nature of built in routines. The format of .dlm files is discussed in The Module Description File.
The module description file is a simple text file that is read by IDL when it starts. The information in this file tells IDL everything it needs to know about the routines supplied by a loadable module. With this information, IDL can compile calls to these routines and otherwise behave as if it contains the actual routine. The loadable module itself remains unloaded until a call to one of its routines is made, or until the user forces the module to load by calling the IDL DLM_LOAD procedure.
Empty lines are allowed in .dlm files. Comments are indicated using the # character. All text from a # to the end of the line is ignored by IDL and is for the user's benefit only.
All other lines start with a keyword indicating the type of information being conveyed, possibly followed by arguments. The syntax of each line depends on the keyword. Possible lines are:
Gives the name of the DLM. This should always be the first non-comment line in a .dlm file.There can only be one MODULE line.
MODULE JPEG
Supplies a short one line description of the purpose of the module. This information is displayed by HELP,/DLM. This line is optional.
DESCRIPTION IDL JPEG support
Supplies a version string that can be used by the IDL user to determine which version of the module will be used. IDL does not interpret this string, it only displays it as part of the HELP,/DLM output. This line is optional.
VERSION 6a
If present, IDL will display this information as part of the output from HELP,/DLM. IDL does not parse this string to determine the date, it is simply for the users benefit. This line is optional.
BUILD_DATE JAN 8 1998
A short one line description of the person or organization that is supplying the module. This line is optional.
SOURCE ITT Visual Information Solutions
This directive is used by ITT Visual Information Solutions to sign the authenticity of the DLMs supplied with IDL releases. It is not required for user-written DLMs.
There should be one STRUCTURE line in the DLM file for every named structure definition supplied by the loadable module. If you refer to such a structure before the DLM is loaded, IDL uses this information to cause the DLM to load. The IDL_Init() function for the DLM will define the structure.
There should be one FUNCTION or PROCEDURE line in the DLM file for every IDL routine supplied by the loadable module. These lines give IDL the information it needs to compile calls to these routines before the module is loaded.
The IDL user level name for the routine.
The minimum number of arguments accepted by this routine. If not supplied, 0 is assumed.
The maximum number of arguments accepted by this routine. If not supplied, 0 is assumed.
Zero or more of the following:
IDL should issue a warning message if this routine is called and !WARN.OBS_ROUTINE is set.
This routine accepts keywords as well as plain arguments.
PROCEDURE READ_JPEG 1 3 KEYWORDS
Every loadable module sharable library must export a single symbol called IDL_Load(). This function is called when IDL loads the module, and is expected to do all the work required to load real definitions for the routines supplied by the function and prepare the module for use. This always requires at least one call to IDL_SysRtnAdd(). It usually also requires a call to IDL_MessageDefineBlock() if the module defines any messages. Any other initialization needed would also go here:
int IDL_Load(void)
This function takes no arguments. It is expected to return True (non-zero) if it was successful, and False (0) if some initialization step failed.
This example creates a loadable module named TESTMODULE. TESTMODULE provides 2 routines:
A function that issues a message indicating that it was called, and then returns the string "TESTFUN" This function accepts between 0 and IDL_MAXPARAMS arguments, but it does not use them for anything.
A procedure that issues a message indicating that it was called. This procedure accepts between 0 and IDL_MAX_ARRAY_DIM arguments, but it does not use them for anything.
The intent of this example is to show the support code required to write a DLM for a completely trivial application. This framework can be easily adapted to real modules by replacing TESTFUN and TESTPRO with other routines.
The first step is to create the module definition file for TESTMODULE, named testmodule.dlm:
MODULE testmodule DESCRIPTION Test code for loadable modules VERSION 1.0 SOURCE ITT Visual Information Solutions BUILD_DATE JAN 8 1998 FUNCTION TESTFUN 0 IDL_MAXPARAMS PROCEDURE TESTPRO 0 IDL_MAX_ARRAY_DIM
The next step is to write the code for the sharable library. The contents of testmodule.c is shown in the following figure. Comments in the code explain what each step is doing.
If building a DLM for Microsoft Windows, a linker definition file (testmodule.def) is also needed. All of these files, along with the commands required to build the module can be found in the dlm subdirectory of the external directory of the IDL distribution.
Once the loadable module is built, you can cause IDL to find it by doing one of the following:
Running IDL to demonstrate the resulting module:
IDL> HELP,/DLM,'testmodule' ** TESTMODULE - Test code for loadable modules (not loaded) Version:1.0,Build Date:JAN 8 1998,Source:ITT Visual Information Solutions. Path: /home/user/testmodule/external/testmodule.so IDL> testpro % Loaded DLM: TESTMODULE. % TESTPRO: This is from a loadable module procedure. IDL> HELP,/DLM,'testmodule' ** TESTMODULE - Test code for loadable modules (loaded) Version:1.0,Build Date:JAN 8 1998,Source:ITT Visual Information Soluctions. Path: /home/user/testmodule/external/testmodule.so IDL> print, testfun() % TESTFUN: This is from a loadable module function. TESTFUN
The initial HELP output shows that the module starts out unloaded. The call to TESTPRO causes the module to be loaded. As IDL loads the module, it prints an announcement of the fact (similar to the way it announces the .pro files it automatically compiles to satisfy calls to user routines). Once the module is loaded, subsequent calls to HELP show that it is present. Calls to routines from this module do not cause the module to be reloaded (as evidenced by the fact that calling TESTFUN did not cause an announcement message to be issued).
IDL Online Help (March 06, 2007)