Chapter Contents |
Previous |
Next |
loadm |
Portability: | SAS/C extension |
SYNOPSIS |
#include <dynam.h>; void loadm(const char *name, __remote /* type */ (**fpp)());
DESCRIPTION |
loadm
loads an executable module named by the argument string
name
and stores a C function pointer
in the location pointed to by the argument
fpp
. If the module has been loaded already, the pointer stored in
fpp
points to the previously loaded
copy. If the module name in the first argument string is prefixed with an
asterisk, a private copy of the module is loaded. Note that
fpp
may reference a function returning any valid
type of data.
RETURN VALUE |
loadm
provides an indirect return value in the form of a function pointer
that addresses the entry point of the loaded module. If the module is in
C, calling the returned function always transfers control to the
_dynamn
function of the module.
If the module to be loaded cannot be found, a
NULL
is stored in the location
addressed by
fpp
.
ERRORS |
CAUTIONS |
Note that a module to be loaded by
loadm
cannot have the entry point defined in
the last 16 bytes of the load module. The library inspects this portion of
the loaded module, and may ABEND if 16 bytes of data are not present. This
situation can arise only if the entry point is an assembler (or other non-C)
routine.
PORTABILITY |
loadm
is not portable. Be aware of system dependencies involving where
load modules may be located and how module names are specified for your operating
system.
IMPLEMENTATION |
The implementation of
loadm
necessarily varies from operating system
to operating system. Under OS/390, modules to be loaded must reside in STEPLIB,
a task library, or the system link list. Under CMS, modules to be loaded
may reside in DYNAMC LOADLIB or in other locations defined by use of the
addsrch
routine. Under CICS, modules
to be loaded must reside in a library in the DFHRPL concatenation and must
be defined to CICS.
USAGE NOTES |
addsrch
does not verify the existence of a location, for example, DYNAMC
LOADLIB. Because in some circumstances the logic of a program may not require
that a location be searched, no verification is done until
loadm
cannot find a load module in any location
defined earlier in the search order.
addsrch
fails only if its parameters are ill-formed.
If
loadm
determines that a location is inaccessible (for example, the LOADLIB
does not exist), the location is marked unusable, and no attempt is made to
search it again.
EXAMPLES |
The use of
loadm
is illustrated by three examples. The first demonstrates the
use of the command for a very simple situation without operating-system dependencies,
while second and third examples are designed to run under OS/390 and CMS respectively.
The third example presents a hypothetical situation under CMS in which
addsrch
)
loadm
)
delsrch
).
#include <dynam.h> int (*fp)(); /* Load a load module named "ADD" and call it. */ loadm("ADD",& fp); sum = (*fp)(1, 3); . . .
STEP I. Put the following declarations in a common header file and name it DYNTABLE:
struct funcdef { /* structure definition for functions */ int (*func1)(); int (*func2)(); /* More functions can go here. */ }; typedef struct funcdef *fptrtable; /* pointer to list of funcdefs */
STEP II. Create the following C source
file and name it DYNAMIC. This file will be compiled and linked to create
a dynamic load module. The
_dynamn
function returns to its caller a structure of function pointers that
can be used to call the individual functions of the load module.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <lcio.h> #include <dynam.h> #include "dyntable.h" /* _dynamn function that returns a list of function pointers which */ /* can be used to invoke other functions in the load module */ fptrtable _dynamn(void) { /* Initialize function pointer table. */ static struct funcdef dyntab = {&func1, &func2 /* ... */}; /* Return pointer to table with the new contents. */ return(&dyntab); } int func1() { printf("func1() was successfully dynamically called!!!\n"); return(0); } int func2() { printf("func2() was successfully dynamically called!!!\n"); return(0); }
DYNAMIC must be compiled using the
sname
compiler option to override the default
assignment of
_dynamn
as
the section name. It may be compiled as re-entrant using the
rent
compiler option. (Note that JCL changes
are required if
norent
compilation
is needed.) During linking, the ENTRY=DYN (or DYNNK for
norent
) parameter must be specified.
STEP III. Create the following C source
file and name it DYNMLOAD. This code demonstrates how to dynamically load
the DYNAMIC load module and how to call the functions pointed to by the
dyntab
table:
#include <stdio.h> #include <string.h> #include <dynam.h> #include "dyntable.h" fptrtable(*fpdyn)(); /* _dynamn function pointer prototype */ int rc1, rc2; /* return codes from calling func_1 */ /* and func_2 */ fptrtable table; /* table of function pointer and names */ /* returned from _dynamn */ */ main() { /* Load DYNAMIC. */ loadm("DYNAMIC", &fpdyn); /* Call _dynamn and return table of function pointers and */ /* name of load module. */ table = (*fpdyn)(); /* Call func1 using function pointer from table. */ rc1 = (*table->func1)(); printf("Dynamically called func1() with rc = %d \n", rc1); /* Call func2 using function pointer from table. */ rc2 = (*table->func2)(); printf("Dynamically called func2() with rc = %d \n", rc2); unloadm(fpdyn); return; }
//* //* COMPILE and LINK module that uses a _dynamn routine that passes //* its caller back a list of function pointers which are used to //* invoke other functions in the load module //* //COMPDYNM EXEC LC370CL,ENTRY=DYN,PARM.C='RENT SNAME(DYNAM)' //C.SYSLIN DD DSN=userid.SASC.OBJ(DYNAMIC),DISP=OLD //C.SYSIN DD DSN=userid.SASC.SOURCE(DYNAMIC),DISP=SHR //* //LKED.SYSLMOD DD DSN=userid.SASC.LOAD(DYNAMIC),DISP=OLD //* //* //* COMPILE and LINK module that dynamically loads the DYNAMIC //* load module and calls functions within the load module //* using the structure of function pointers returned. //* //CLEMAIN EXEC LC370CLG //C.SYSLIN DD DSN=userid.SASC.OBJ(DYNMLOAD),DISP=OLD //C.SYSIN DD DSN=userid.SASC.SOURCE(DYNMLOAD),DISP=SHR //* //LKED.SYSLMOD DD DSN=userid.SASC.LOAD(DYNMLOAD),DISP=OLD //
A C source file, NEPTUNE C (listed below), is to be dynamically loaded and
executed. The file contains the function
neptune
.
#include <stdio.h> void neptune(char *p) { puts(p); return; }
STEP I. Make the function
neptune
into a separate, loadable module by link-editing
the TEXT file into a CMS LOADLIB file. The following steps are required:
_dynamn
.
#include <stdio.h> void _dynamn(char *p) { puts(p); return; }
All C load modules (except the one that includes
main
, of course) must define one
function named
_dynamn
.
sname
compiler option to override the default
assignment of
_dynamn
as
the sname. See Chapter 7, "Compiler Options," in the SAS/C Compiler
and Library User's Guide for more information about the
sname
compiler option.
LKED NEPTUNE (LIBE DYNAMC NAME NEPTUNE
STEP II. The function
neptune
now exists in a form loadable by
loadm
. Invoke
loadm
to load the module as
follows:
#include <dynam.h> main() { int (*fp)(); /* Declare a function pointer */ loadm("NEPTUNE",&fp); /* Load NEPTUNE */ if (fp) { /* Check for errors */ (*fp)("Hello, Neptune, king of the C!"); unloadm(fp); /* Delete NEPTUNE */ } else puts("NEPTUNE failed to load."); exit(0); }
STEP III. The previous step used the default
search location DYNAMC LOADLIB (see
addsrch
); thus, no call to
addsrch
is required. If you use some other filename for the LOADLIB,
specify it in a call to
addsrch
before invoking
loadm
.
The following is an example:
#include <dynam.h> main() { SEARCH_P sp; /* Declare a SEARCH_P value */ int (*fp)(); /* specify "NEWLIB LOADLIB *" */ sp = addsrch(CMS_LDLB,"NEWLIB *",""); loadm("NEPTUNE",& fp); if (fp) { (*fp)("Hello, Neptune, king of the C!"); unloadm(fp); } else puts("NEPTUNE failed to load."); delsrch(sp); /* remove NEWLIB LOADLIB from the search order */ exit(0); }
sp = addsrch(CMS_NUCX,"",""); loadm("NEPTUNE",&fp);
The function must exist as a nucleus extension before
invoking
loadm
. This facility
is useful, for example, in testing a single load module that you plan to replace
in an existing LOADLIB.
RELATED FUNCTIONS |
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.