Futurebasic/Language/Reference/enterproc
ENTERPROC statement
[edit | edit source]ENTERPROC
[edit | edit source]Statement
[edit | edit source]✔ Appearance ✔ Standard ✔ Console
Syntax
[edit | edit source]Syntax 1:
"statementLabel" ENTERPROC [(intVar1 [,intVar2 ...])] [statementBlock] EXITPROC [= intVar3]
Syntax 2:
"statementLabel" ENTERPROC FN fnName[(intVar1 [,intVar2 ...])] [= type] [statementBlock] EXITPROC [= returnValue]
Description
[edit | edit source]The ENTERPROC
statement marks the beginning of a procedure block, which must end with an EXITPROC
statement. A procedure block is used to implement a function that uses the Pascal calling convention, which is a certain way that the function manipulates the stack. The most common use for this kind of function is to implement Toolbox "callback" procedures (often called "application-defined routines" in Inside Macintosh). Such callback procedures must use the Pascal calling convention.
An ENTERPROC
procedure block can only appear within the "main" scope of the program; not within a LOCAL FN
. Each of the intVar
's must be either a short (2-byte) integer variable or a long (4-byte) integer variable, or a POINTER
or HANDLE
variable. The statementBlock
can contain any collection of FB statements except another ENTERPROC
...EXITPROC
block (i.e., procedure blocks cannot be nested). The scope of all the variables referenced in the procedure block is either global (if the variable was declared earlier in a BEGIN GLOBALS
...END GLOBALS
block) or local to the procedure block itself.
A procedure block is called when some caller (typically a Toolbox routine) refers to the procedure's address in memory; your program can use the PROC"statementLabel"
function to get that address. Typically, your program would pass that address to the Toolbox routine, to identify the procedure block as a "callback" procedure. When the procedure block is called, intVar1
, intVar2
, etc. are assigned values which are passed by the caller. When the EXITPROC
statement is reached, control is returned back to the caller, and if intVar3
(or returnValue
) was specified, its value is returned to the caller.
It's important that you know the number and types of parameters (if any) that the caller expects to pass to your procedure block, and that you set up the intVar1
, intVar2
(etc.) parameters in the ENTERPROC
statement accordingly. Likewise, you should know whether the caller expects your procedure block to return a value and, if so, whether the caller expects a 2-byte or a 4-byte value. If you use Syntax 1, you should specify a variable of the appropriate size in intVar3
if the caller expects a return value; otherwise you should omit intVar3
. If you use Syntax 2, you should specify the name of a 2-byte or 4-byte type (such as INT
or POINTER
) in the type
parameter, and specify a returnValue
expression of that type, if the caller expects a return value; otherwise, you should omit the type
and the returnValue
. If you do not set up the input parameters and the return parameters correctly in your ENTERPROC
and EXITPROC
statements, then your program is likely to crash when the procedure block is called. See <a href="app.%20c%20data%20types.html">Appendix C</a>: Data Types and Data Representation, for a list of valid 2-byte and 4-byte variable types.
If you use Syntax 2, you can also execute a procedure block by using the FN <userFunction>
statement, although there is generally little reason to do this (it's usually better to use a LOCAL FN
when you want to create a procedure that will be explicitly called by your program).
Note:
When your program starts up, it will not automatically "skip over" the lines in a procedure block, the way it skips over the lines in a LOCAL FN
. In order to prevent your procedure block from being executed inadvertently, you should either branch around the procedure block using GOTO
, like this:
GOTO "Detour" "myProc1" ENTERPROC(var&) : EXITPROC "myProc2" ENTERPROC(var1%, var2&) : EXITPROC = result& "Detour"
or you should place the procedure block after an END
statement, like this:
'[main part of program here] END '======= Procedures ======= "myProc1" ENTERPROC(var&) : EXITPROC "myProc2" ENTERPROC(var1%, var2&) : EXITPROC = result&
See Also
[edit | edit source]CALL <address>; Appendix C: Data Types and Data Representation