CALL Command [ HP ALLBASE/4GL Developer Reference Manual Vol. 2 ] MPE/iX 5.0 Documentation
HP ALLBASE/4GL Developer Reference Manual Vol. 2
CALL Command
The CALL command provides dynamic loading of routines written in the C
programming language.
Formats
[ { *R } ]
CALL [ *REFRESH] fn_name library_name [ parm_n { { datatype}}...]
[ { *V } ]
Parameters
*REFRESH
If you specify *REFRESH, ALLBASE/4GL saves the current screen settings
and turns the screen control over to the C function. While the CALL
command executes, messages from the C function are displayed on the
screen. After the function completes, ALLBASE/4GL repaints the original
screen. If you do not use the *REFRESH argument, C function information
may overwrite available fields on the screen, and the original screen is
not repainted.
The *REFRESH modifier has two effects. Before the library routine is
called, the terminal is set to the terminal setting that exists before
ALLBASE/4GL is invoked. On return from the library routine, the terminal
is restored to the original terminal setting.
fn_name
The fn_name must be one of the following, whose content contains the name
of the C function you want to call.
* alphanumeric constant
* screen field name
* scratch-pad field name
* file record field reference
* work area field reference
* literal
* variable
library_name
The library_name must be one of the following, whose content contains the
name of the HP-UX shared library where you want ALLBASE/4GL to search for
the called function.
* alphanumeric constant
* screen field name
* scratch-pad field name
* file record field reference
* work area field reference
* variable
* literal
parm_n
These are the optional parameters that can be passed to and from the
library function. The type of the variable passed to the C function is
determined by the storage used for the ALLBASE/4GL item and must match
those required by and used by the function. If you use a parameter, you
must specify the ALLBASE/4GL storage type for each parameter used.
For each argument used in the CALL command two modifiers are specified.
The first modifier must have the value *R or *V, which signifies one of
the following:
*R Argument by reference (any change to the value is reflected in
ALLBASE/4GL).
*V Argument by value (any change to the value is not reflected in
ALLBASE/4GL).
The second modifier specifies the argument type, which may be the value
*INT, *LONG, *CHAR, *FLOAT, or *DOUBLE. The arguments correspond to the
native C language pointer to SHORT, pointer to INT, pointer to CHAR
(string), pointer to FLOAT and pointer to DOUBLE. Any argument of type
*CHAR (string) is terminated with a NULL character before being passed to
the library routine to easily determine string lengths. The NULL
character is ignored by ALLBASE/4GL on return.
data type
Data types are:
* *CHAR
* *INT
* *LONG
* *FLOAT
* *DOUBLE
The following table shows the ALLBASE/4GL storage types (as per the
storage fields in the data dictionary) and the corresponding C storage
types.
-----------------------------------------------------------------------------------------------
| | | |
| 4GL Data Type | Storage Type | C Type |
| | | |
-----------------------------------------------------------------------------------------------
| | | |
| CHAR | C | Native C pointer to character data type. |
| | | Arguments of this type are terminated with |
| | | a NULL character before being passed to the |
| | | library routine. The NULL character is |
| | | ignored by ALLBASE/4GL on return. |
| | | |
-----------------------------------------------------------------------------------------------
| | | |
| INT | I | Address of short integer data type |
| | | |
-----------------------------------------------------------------------------------------------
| | | |
| LONG | L | Address of integer data type |
| | | |
-----------------------------------------------------------------------------------------------
| | | |
| FLOAT | F | Address of single-precision floating-point |
| | | data type. |
| | | |
-----------------------------------------------------------------------------------------------
| | | |
| DOUBLE | D | Address of double-precision floating-point |
| | | data type. |
| | | |
-----------------------------------------------------------------------------------------------
NOTE There is no corresponding C type for packed decimal, so any
ALLBASE/4GL item with this storage type cannot be passed to a C
function. It can, however, be MOVEd to another 4GL item with a
non-packed decimal storage type and used from there.
The values for these parameters are placed in ALLBASE/4GL storage
elements. Any of the following types of ALLBASE/4GL storage elements can
be used as parameters:
* Variables
* Screen field references
* Scratch-pad field references
* File record field references
* Work area field references
* File record buffers
* Work area buffers
* Communication area fields
The parameters can be passed by reference (*R), which means that any
change made to the parameter in the C function is reflected in
ALLBASE/4GL. If you pass the parameter by value (*V), the C function can
modify the parameter, but it is not reflected in the parameter when
returning from the function.
Parameters are always passed to the C function by address. This means
that any C functions called by ALLBASE/4GL must declare parameters as
pointers. See the type declarations in Example 3 in the next section for
clarification.
Description
CALL allows developers to use existing code libraries and develop
applications faster. The CALL command is similar to the EXTERNAL command
except that it executes routines in the same process as ALLBASE/4GL
whereas the EXTERNAL command starts up one or more completed programs as
separate processes.
The CALL command enables the routine to become an active part of the
ALLBASE/4GL process, providing maximum flexibility and high performance.
With this enhancement, ALLBASE/4GL becomes truly extensible. Developers
can add their own functionality to ALLBASE/4GL, build up libraries of
object code, and create a development system geared toward maximum
productivity.
The CALL command executes a function stored in a shared library. The
function must be written in the C language and the variables must match
exactly the variables required by the C function. Arguments can be
passed to the library routine by value (*V) or by reference (*R).
WARNING It is the developer's responsibility to ensure that the type and
number of parameters agree between ALLBASE/4GL and the C
function. If they don't agree, this would result in an error
that would not be detected by ALLBASE/4GL. It is also the
developer's responsibility to ensure that the C function code is
not faulty. Since the C function is executing in the same
process as ALLBASE/4GL, anything that causes the C function to
abort also causes ALLBASE/4GL to abort. For instance, a
segmentation violation due to faulty C code causes ALLBASE/4GL
to abort.
Example 1
CALL V-functionx V-my_lib V-my_variable *V *INT
This example passes the address of the ALLBASE/4GL variable my_variable
to the C function. Any changes to the variable are not reflected in the
variable when control returns to ALLBASE/4GL.
This example assumes that no information needs to be written to the
screen and therefore, the *REFRESH option is not used.
Example 2
CALL "functionx" V-my_lib V-my_variable *R *INT
This example also passes the address of the ALLBASE/4GL variable
my_variable so that the C function can actually change it. However, any
changes made to the variable in the C function are also reflected in the
variable when control returns to ALLBASE/4GL.
This example assumes that no information needs to be written to the
screen and therefore, the *REFRESH option is not used.
Example 3
MOVE "2" V-var1
MOVE "This is a test string" V-var2
MOVE "mylib.sl" V-lib_name
MOVE "my_func" V-func_name
CALL *REFRESH V-func_name V-lib_name V-var1 *R *INT V-var2 *V *CHAR
This example shows the relationship between the ALLBASE/4GL command and
the associated function that it calls. On returning to ALLBASE/4GL the
variable V-var1 is incremented by 1. The standard I/O function printf is
used in this example.
The function my_func could be as follows:
#include <stdio.h>
int my_func(number, string)
int *number; /* type L in ALLBASE/4GL */
char *string; /* type C in ALLBASE/4GL */
{
*number = *number + 1; /* increment the number */
printf("The string is %s \n Press return to continue.",string);
getcchar ();
return 0;
}
NOTE The function return value is put into the communication area
*ERROR. The function return type must be of type int.
MPE/iX 5.0 Documentation