|routine||Name of the external subroutine to call.|
|arglist||Optional — Comma-delimited list of arguments to pass to the external subroutine. The number of arguments specified must match the number of argument defined for the subroutine. Specify the MAT keyword before an array argument.|
The CALL statement can be used to call an external subroutine and to optionally pass arguments to that subroutine. The external subroutine must have been compiled and cataloged. You can use the RETURN statement within the external subroutine to return control to the next statement following the CALL statement.
The RETURN statement will first return from internal GOSUB subroutines and then return from the external SUBROUTINE when the GOSUB stack is exhausted.
You can use routine to specify the external subroutine either directly or indirectly:
The routine argument can specify the exact name under which the subroutine was cataloged.
The routine argument can specify the name of a variable that contains the name of the subroutine. A variable of this type is prefaced with the @ symbol. A variable name can be a local variable, or an element of an array.
If the routine name begins with an asterisk (*), CALL first looks it up as a local routine. If not found, CALL looks it up as a global routine. If still not found, CALL generates an error. Note that *routine processing is different in UniData emulation, as described below.
The argument list can contain any combination of regular variables and array variables. An array variable must be dimensioned in the calling program using the DIM statement. Caché dimensionless arrays can also be passed to the subroutine as arguments, providing they are DIMensioned using DIM var().
In arglist, an array variable name must be preceded by the MAT keyword. The following is an argument list that specifies a literal, a regular variable, and an array variable:
CALL MySub(123,myvar,MAT myarray)
By default, all arglist arguments are passed by reference. If the subroutine changes the value of an argument passed by reference, this value is also changed in the calling program. You can specify that an argument is to be passed by value by enclosing the argument name in parentheses (which changes the variable in to an expression; expressions are always passed by value). If the subroutine changes the value of an argument passed by value, the value of this argument in the calling program remains unchanged.
You can also use the COMMON statement to make specified variables available to all external subroutines. You should avoid calling SUBROUTINEs using a variable that is declared in COMMON as a subroutine argument as you will have two references to the same variable in the subroutine – the original COMMON reference, and the subroutine parameter.
An array may be dimensioned differently in the subroutine than it is in the calling program, but that the number of dimensioned elements should remain the same. Hence a variable A declared as DIM A(10) may be declared as A(5,2) in the subroutine.
CALL works on only a single value at a time. If you specify a CALL with a multivalue argument, Caché MVBasic invokes CALL repeatedly, once for each value in the multivalue argument. The called external subroutine can only return single-valued arguments.
CALL, ENTER, SUBR, and GOSUB
The CALL statement is used to call an external subroutine with parameter passing and return. If you do not need to pass parameters or return to the calling program, you can use ENTER to call an external subroutine.
The SUBR function is used to call an external subroutine that returns a value. The GOSUB statement is used to call an internal subroutine.
The following example uses CALL to pass arguments by reference:
Main x="Burma" y="Myanmar" PRINT x ! Returns "Burma" CALL MapSub(x,y) PRINT x ! Returns "Myanmar" MapSub(name,newname) PRINT name ! Returns "Burma" name=newname PRINT name ! Returns "Myanmar" RETURN
The following example uses CALL to pass an argument by value by using parentheses around the argument:
Main x="Burma" y="Myanmar" PRINT x ! Returns "Burma" CALL MapSub((x),y) PRINT x ! Returns "Burma" MapSub(name,newname) PRINT name ! Returns "Burma" name=newname PRINT name ! Returns "Myanmar" RETURN
In UniData and UDPICK emulations, a routine name with an initial character of * is handled as a global routine name. CALL removes the leading * and then looks up the resulting routine name as a global routine. If the runtime environment is not UniData emulation, a normal lookup is done on a routine name with a leading * character.
The use of $OPTIONS UNIDATA in the MVBasic source file does not activate this behavior. The handling of names with leading * is determined by the user setting in the command language at runtime. Therefore, to activate this behavior, the CEMU command must set UniData emulation before running a program that calls a routine name with a leading *.