Futurebasic/Language/Reference/enterproc

From Wikibooks, open books for an open world
Jump to navigation Jump to search

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