Chapter Contents |
Previous |
Next |
Using the indep Option for Interlanguage Communication |
The C Execution Framework |
The C
execution framework includes the stack from which
save areas and auto storage are allocated, the pseudoregister vector that
contains
extern
and
static
data for reentrant programs, and the C Run-Time Anchor Block
(CRAB). The CRAB contains constants and other information used by both compiled
code and the library. The C framework also includes the default signal handlers
set up by the library. When the C framework is active, register 12 addresses
the CRAB. C functions compiled without the
indep
option expect register 12 to
address the CRAB on entry; if it does not, the results are unpredictable.
When a C program compiled without the
indep
option is executed,
the C framework is created by the L$CMAIN library routine. The execution of
this routine precedes execution of the
main
function. L$CMAIN obtains storage
for the CRAB, the pseudoregister vector, and the initial stack and heap and
sets register 12 to address the CRAB.
C Execution Framework Creation with indep |
The C framework is created when the first (or initial)
C function is called. (This function is not necessarily named
main
.) Because this function
is called before the C framework is created, it must be compiled with
indep
.
(See main Function Considerations for one exception.)
When a C source file is compiled with the
indep
option, all the functions
in the resulting object file have the following properties:
Therefore, a function compiled by
indep
can be called directly
from outside of the C execution framework (for example, with another high-level
language's framework active).
The primary characteristic of the object code generated
when the
indep
compiler option is used is that the L$UPREP routine is invoked
whenever a function compiled with the
indep
option is called. L$UPREP determines
whether the C execution framework has been created. If the C framework has
been created, the CRAB address is loaded into register 12 and execution of
the called function proceeds normally. If not, L$UPREP invokes L$UMAIN, an
initialization routine in the run-time library, to create the C framework.
After the C framework is created (and the CRAB address is stored in register
12), execution of the initial function proceeds normally.
Because all functions compiled with
indep
invoke L$UPREP, it
does not matter which of these functions is called first. Whichever function
is called first creates the C framework.
Specifying Run-Time Library Options |
Normally, when a C program is invoked by the operating
system, run-time library options are specified as part of the argument list
passed by the operating system. However, when the initial function is compiled
with the
indep
option, the arguments can have any type and therefore cannot
be modified, or even inspected, by the library. For this reason, another
mechanism must be used in such an application to specify run-time options.
One method is the normal technique of initializing external
int
variables named
_options
and
_negopts
and the external
char
variable named
_linkage
to specify the options required.
(Refer to Run-Time Argument Processing for more details.) However, this technique can be used only when the options
required are constant and known at compile time.
Because SPE does not support run-time options, L$URTOP is not used with the SPE framework.
The following example shows a typical L$URTOP routine:
Sample L$URTOP Routine
********************************************************************** * * * L$URTOP is an optional routine to provide runtime arguments to * * Indep applications. * * * * In this example, the normal action is to specify a minimal set of * * run-time options. However by zapping the location DEBUGOPT, two * * completely different sets of options can be provided. * * * * When DEBUGOPT is set to 1 a different set options more suitable * * for limited debugging is specified. This set of options also * * define environment variables (APL1) meaningful to the application. * * Additionally, the runtime options at label ALTOPTST can be zapped * * to provide an entirely different set of runtime options when * * DEBUGOPT is set to 1. * * * * When DEBUGOPT is set to 2 a different set of options provide the * * information necessary to start the SAS/C Remote Debugger. * * * ********************************************************************** L$URTOP CSECT SPACE ********************************************************************** * Ensure AMODE/RMODE match those of the SAS/C Library Default * ********************************************************************** L$URTOP RMODE ANY L$URTOP AMODE 31 SPACE USING *,15 Tell Assembler B SETARGS Branch around eye-catcher DC AL1(L'EYECATCH) EYECATCH DC C' L$URTOP - Sample' DC XL1'00' Filler SPACE * Switch to determine which set of runtime options will be used SPACE DEBUGOPT DC XL1'00' SPACE SETARGS DS 0H STM 14,12,12(13) Save entry regs in callers area SPACE LA 1,STDOPTS Default to standard runtime CLI DEBUGOPT,0 Has switch been set for alternate? BE RETARGS No, return standard runtime SPACE * Alternate has been requested, set as indicated or take the default CHKALT DS 0H Check for Alternate runtime CLI DEBUGOPT,1 Has switch been set for alternate? BNE CHKRMT No, check for Remote Debugger LA 1,ALTOPTS Yes, return optional runtime B RETARGS CHKRMT DS 0H Check for Remote Debugger Setup CLI DEBUGOPT,2 Has switch been set for Debug Rmt? BNE RETARGS No, return standard runtime LA 1,DBGRMT Yes, return Debugger Remote runtime SPACE RETARGS LR 15,1 Point R15 at runtime arguments DROP 15 SPACE L 14,12(,13) Restore R14 LM 0,12,20(13) Restore other registers BR 14 Return to caller LTORG , ********************************************************************** * Minimal Options * ********************************************************************** STDOPTS DC AL2(L'STDOPTST) STDOPTST DC C'=VERSION' Standard - runtime SPACE ********************************************************************** * Alternate options providing additional information * ********************************************************************** ALTOPTS DC AL2(L'ALTOPTST) Alternate- runtime ALTOPTST DC CL80'=BTRACE =WARNING =FDUMP =APL1=DEBUG =STORAGE' DC 0D'0' Filler SPACE ********************************************************************** * Alternate options which provide setup information for the SAS/C * * Remote Debugger. * ********************************************************************** DBGRMT DC AL2(DBGLEN) RmtDebug - runtime RMTOPTS DC C'=_DB_COMM=TCPIP ' DC C'=_DB_HOST=124.383.1.2 ' DC C'=_DB_PORT=3123 ' DC CL80'=DEBUG =VERSION' DC 0D'0' Filler DBGLEN EQU *-RMTOPTS SPACE END
C Execution Framework Access |
Once L$UMAIN has created the C execution framework,
it is necessary to ensure that it is accessible when any C function executes.
For a function compiled with
indep
, L$UPREP is responsible for making the C framework
accessible by loading the CRAB address into register 12. Functions compiled
with
indep
can thus be invoked from outside the C framework (for example,
from another high-level language).
Functions compiled with
indep
can also be invoked
from other C functions. In this case, the C framework is already accessible.
L$UPREP is responsible for determining whether a function compiled with the
indep
option was called from C or from a non-C routine and for avoiding unnecessary
or incorrect processing if the call is from C. If you modify the supplied
L$UPREP routine only by replacing the L$UCENV macro, this check is performed
automatically, and the code to find the C framework generated by L$UCENV is
executed only for a call from non-C code.
C functions compiled without
indep
also can be used
in a multilanguage environment. Because such functions do not invoke L$UPREP,
they can be called only from other C functions. Calls to these functions execute
slightly faster because L$UPREP is not invoked, so you may want to compile
only functions that are called from C without using the
indep
option.
C Execution Framework Termination |
After all C functions have completed execution and
before
the current task or command returns to the operating system, the C framework
should be terminated. This enables memory to be freed, output buffers to
be flushed, files to be closed, operating system exits such as ABNEXITs and
ESTAEs to be cleared, and so on. When a C program that was compiled without
indep
terminates, the C framework is terminated automatically. When you use
indep
for calling C from another language, it usually is your responsibility to
terminate the C framework after all calls to C functions have completed.
Unless the initial C function is named
main
, the C framework created
by the initial call to C exists indefinitely. (See main Function Considerations for information on this
special case.) Therefore, subsequent C functions can access external variables
set by previous functions, read and write opened files, and so on. In this
case, you should ensure that the C execution framework is terminated when
all C functions have completed.
The execution framework may also be terminated by calling
the standard
exit
function, but
exit
can be called only by a C routine, while L$UEXIT
can be called by either C or non-C code.
Note that both L$UEXIT and
exit
return to the program
that called the first currently active C function. Since L$UEXIT is a C function,
L$UEXIT returns to the routine that called it, assuming no other C routine
was active at the time of the call. Because
exit
must be called by a C function,
exit
never returns to its caller.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.