Q(uick)BASIC Statement (Non-BASIC): CALLS

Quick View

CALL, CALLS

Statements that transfer control to a procedure written in another programming language

Worth knowing

Useful and cross-version information about the programming environments of QBasic and QuickBasic.

Syntax
  • CALL name [( call-argumentlist )]
  • name [ call-argumentlist ]
  • CALLS name [( calls-argumentlist )]
Description/Parameter(s)
name The name of the procedure being called. A name is limited to 40 characters.
call-argumentlist The variables or constants passed to the procedure. The syntax of a call-argumentlist is described below.
calls-argumentlist A list containing the variables and constants that CALLS passes to the procedure. Entries are separated by commas. Note that these arguments are passed by reference as far addresses, using the segment and offset of the variable. You cannot use BYVAL and SEG in a calls- argumentlist.

A call-argumentlist has the following syntax: [[{BYVAL|SEG}]argument][,[{BYVAL|SEG}]argument]…

If argument is an array, parentheses are required: [[{BYVAL|SEG}]argument[()]][,[{BYVAL|SEG}]argument]…

BYVAL Indicates the argument is passed by value, rather than by near reference (the default)
SEG argument Passes the argument as a segmented (far) address A BASIC variable, array, or constant passed to a procedure

CALLS is the same as using CALL with a SEG before each argument: every argument in a CALLS statement is passed as a segmented address.

Note: The syntax described above does not correctly invoke a BASIC procedure -- only procedures in other languages. See the CALL (BASIC) statement for the other syntax.

If the argument list of either statement includes an array argument, the array is specified by the array name and a pair of parentheses:

  • DIM IntArray(20) AS INTEGER
  • CALL ShellSort(IntArray() AS INTEGER)

When you use the CALL statement, the CALL keyword is optional. However, when you omit CALL, you must declare the procedure in a DECLARE statement. Notice also that when you omit CALL, you also omit the parentheses around the argument list.

The result of the BYVAL keyword differs from BASIC's pass by value:

  • CALL Difference (BYVAL A,(B))

For the first argument, only the value of A is passed to Difference. In contrast, (B) is evaluated, a temporary location is created for the value, and the address of the temporary location is passed to Difference. You can use BASIC's pass by value for an argument, but you must write the procedure in the other language so the procedure accepts an address.

Note: If name refers to an assembly-language procedure, it must be a PUBLIC name (symbol). PUBLIC names beginning with "$" and "_" may conflict with names used by the BASIC run-time system. Duplicate names cause a linker error message "Symbol already defined" to be generated.

Be careful using the SEG keyword to pass arrays because BASIC may move variables in memory before the called routine begins execution. Anything in an argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables, arithmetic expressions, or arrays indexed without the use of intrinsic or user-defined functions.

Differences from BASICA

  • Assembly-language programs invoked from BASICA that have string arguments must be changed because the string descriptor is now four bytes long. The four bytes are the low byte and high byte of the length followed by the low byte and high byte of the address.
  • To locate the routine being called, the BASICA CALLS statement uses the segment address defined by the most recently executed DEF SEG statement. There is no need to use DEF SEG with the CALLS statement because all arguments are passed as far (segmented) addresses.
Example

See the VARPTR function programming example, which uses a CALL statement to invoke a C procedure.

Syntax
  • CALL name [( call-argumentlist )]
  • name [ call-argumentlist ]
  • CALLS name [( calls-argumentlist )]
Description/Parameter(s)

The CALL and CALLS statements transfer control to a procedure written in another language. (A different CALL statement is used to transfer control within a BASIC program.)

CALL name [( call-argumentlist )]
  name [ call-argumentlist ]
CALLS name [( calls-argumentlist )]
  • If name refers to an assembly-language procedure, it must be a name declared with PUBLIC (symbol).
  • The call-argumentlist has the following syntax:

  • Syntax 1 (for non-array arguments):
  • [[{BYVAL|SEG}] argument] [,[{BYVAL|SEG}] argument]…
  • Syntax 2 (for array arguments):
  • [argument()] [, argument()]…
BYVAL Passes the argument by value rather than by reference (the default is by reference). BYVAL cannot be used if the argument is an array.
SEG Passes the argument as a segmented (far) address. SEG cannot be used if the argument is an array.
argument A BASIC variable, array, or expression passed to a procedure. Use the first syntax if argument is not an array; use the second if argument is an array. (The array is specified by the array name and a pair or parentheses.) For example:
  • DIM IntArray(20) AS INTEGER
  • CALL ShellSort(IntArray() AS INTEGER)

  • The calls-argumentlist has the following syntax:
    [argument] [,argument]…
argument A BASIC variable or expression. These arguments are passed by reference as far addresses, using the segment and offset of the variable. Whole array arguments cannot be passed by CALLS.

Usage Notes

  • The result of the BYVAL keyword differs from BASIC's pass by value:

  • CALL Difference(BYVAL A, (B))
A Only the value of A is passed to Difference.
(B) Is evaluated, a temporary location is created for the value, and the address of the temporary location is passed to Difference
  • You can use BASIC's pass by value for an argument, but the procedure in the other language must accept an address (because the address of the temporary location is passed).
  • Be careful using the SEG keyword to pass elements of arrays because BASIC may move arrays in memory before the called routine begins execution. Anything in an argument list that causes memory movement may create problems. You can safely pass variables using SEG if the CALL statement's argument list contains only simple variables, arithmetic expressions, or arrays indexed without the use of intrinsic or defined functions.
  • The CALL keyword is optional when you use the CALL statement. When you omit CALL, you must declare the procedure in a DECLARE statement. When you omit CALL, you omit the parentheses around the argument list.
  • CALLS is the same as using CALL with a SEG before each argument: every argument in a CALLS statement is passed as a segmented address.
Example

This example uses the CALL and CALLS statements to pass a BASIC array to a C function.
Note: To run this program, you must separately compile the C function with the medium-model (/AM) switch and place the object module in a Quick library or link it to the BASIC main program.

DEFINT A-Z DECLARE SUB AddArr CDECL (SEG Array, SEG Num) DIM A(1 TO 100) AS INTEGER 'Fill the array with the numbers 1 to N. N = 15 FOR I = 1 TO N A(I) = I NEXT I 'Call the C function using CALLS the first time 'and increment all array elements by 1. CALLS AddArr(A(1), N) 'Call the same C function again using CALL and 'increment all array elements by 1. CALL AddArr(A(1), N) 'Print the modified array. All elements will be incremented 'by a total of two. For example, what was 1 will now be 3. FOR I = 1 TO N PRINT A(I), NEXT I END 'C Function addarr. ' '/* Add one to the first num elements of array arr.*/ 'void far addarr(arr,num) 'int far *arr; 'int far *num; '{ ' int i; ' for(i=0;i<*num;i++) arr[i]++; '}