call statement

The call statement transfers control to an external FlashBASIC or BASIC subroutine and optionally passes a list of arguments to it.

Syntax

call cataloged.program.name{(arg{,arg...})}
call @ program.name.var{(arg{,arg...})}
call "file.ref program.name"{(arg{,arg...})}

Description

Arguments must be separated with a comma. When passing arguments, the same number must occur in the call statement as are declared in the subroutine statement, which must occur as the first executable line of the external subroutine. There is a maximum of approximately 200 arguments. The subroutine can return values to the calling program in variable arguments.

The external subroutine must ultimately execute a return statement to continue program execution at the statement immediately following the call statement. Subroutines that do not return terminate execution.

Note: For Windows:
  • Locally defined variables in external subroutines (and files opened to local file variables) are automatically abandoned or closed upon return.

  • Use caution when making recursive calls. If the depth of the call is too deep, the thread will be terminated.

The call @, or indirect call form allows the statement to use the subroutine name assigned to a specific variable.

Called subroutines must be compiled and cataloged separately from the calling program. The arguments passed between (to and from) the program and subroutine are not label-sensitive, but are order-sensitive. The arguments listed in the subroutine statement and the arguments listed in the call statement can be different. The subroutine receives the results of arguments in the order in which they are specified in the argument list.

Variable arguments are passed to the subroutine at call time and from the subroutine at return time.

Arrays can be passed between programs and subroutines. The array in the program and called subroutine must contain the same number of elements. If dimensioned arrays are used, the arrays should be dimensioned exactly the same in both the program and subroutine. Alternately, a dim statement can be specified without the actual number of elements. The array is properly initialized at run time.

Arguments listed in both the call and subroutine statements should not be duplicated in the argument lists. Arguments that are also defined as common variables in both calling programs and subroutine programs should not be used in argument lists because the data is already accessible through the common allocations. Violation of these rules can result in unpredictable values being passed between the programs.

It is possible to specify the file path name followed by a space followed by the actual subroutine name. To do this, the file path and program name can be passed via a variable to an indirect call, or the string can be enclosed in quotation marks and embedded directly into the program text. Specifying a direct file reference and program name eliminates the need for cataloging subroutines when an application is used from other accounts.

On D3 9.0, if the subroutine is not cataloged, FlashBASIC or BASIC attempts to locate the subroutine object code in the same dictionary in which the program's object code resides. This eliminates the need to catalog most subroutines.

Note: The initial overhead for an external subroutine call requires the program name be found in the master dictionary. This item points to the object code file. The object pointer is read next and it points to the actual object code.

Dynamic array elements passed to subroutines are treated as function results and are therefore not updated after the call returns.

Calling BASIC subroutines

When calling a subroutine from BASIC, a variable is created which is associated to the name of the subroutine in the object code of the program performing the call. For improved performance, the location of the subroutine is stored in the variable so that subsequent calls do not have to look up the location of the object code. This also occurs using the format filename subname”(parameters). However the @subname(parameters) syntax does not allow for this optimization. The name of the subroutine is stored in the subname variable, rather than the address of the object code. Because the subroutine name may change from call to call, the name must be resolved every time. As a result, it may appear that the basic protection functionality is not properly functioning. For example, a program containing:

call sub(x)
call “sub”(x)
mysub = ‘sub’; call @mysub

Initially all three lines would call the same subroutine, however the @subname needs to be looked up each time it is executed, it resolves to the new subroutine after it is compiled - whereas the other formats would still be pointing to the old object code (thus the need for the basic protection).

Calling FlashBASIC subroutines

When calling subroutines from FlashBASIC, the format of the calls do not affect performance. However, the name of the subroutine affects how the program is located in memory. Using the three forms below, and assuming you are in the myacct account and sub only exists in the bp file, would load the sub subroutine into memory three times.

call sub(x)
call “bp sub”(x)
mysub = ‘myacct,bp, sub’; call @mysub
Note: This is not due to the three different formats, but because the name of the subroutine is referenced three ways (sub, “bp sub”, and ‘myacct,bp, sub’).

Using the forms below instead would only load the sub subroutine once in memory and would be located quickly for any of the three different calls. This means that if sub is recompiled while a process has it loaded in memory, it will never call the new version until the old one is removed from memory by going to TCL.

call sub(x)
call “sub”(x)
mysub = ‘sub’; call @mysub

Example(s)

Direct call:

call process.lines(ID,order.item(1))

or

call "process.lines"(ID,order.item(1))

With or without quotation marks, this example still calls the process.lines subroutine.

Indirect call:

program.var = "process.lines"
call @program.var(ID,order.item(1))

This example calls the subroutine name held as a string in the variable program.var.

Indirect call with full path name:

program.var = "dm,bp, process.lines"
call @program.var(ID,order.item(1))