
FB II Compiler
PG PRO
Debugging
Memory
System
Mathematics
Resources
Disk I/O
Windows
Controls
Menus
Mouse
Keyboard
Text
Fonts
Drawing
Sound
Clipboard
Printing
Communication
ASM
|
DISK I/O
Understand the = symbol passed with a parameter to a function
There is following line in the ListVolme FN (sample source), but I cannot understand what the "=" statement means.
FN ListFolder (=pbPtr&, pbPtr&.ioDirID&)
To understand how this works, you need to look at the ListFolder function itself, and the way things would normally work. The function definition should look something like this:
LOCAL FN ListFolder (@pbPtr&,dirID&)
You would normally call the function like so:
FN ListFolder(paramBlock,theDirID%)
Where paramBlock normally is the actual param block (not a pointer to a param block). A param block is usually DIM'ed something like this:
DIM paramBlock.80
The ListFolder function would then use the @ symbol to generate a pointer to the param block "on the fly", and would use the pointer inside of the function.
But in your case, you already _have_ a pointer to your param block (pbPtr&). Rather than passing the param block itself, and making the compiler generate a pointer on the fly, it would be better to just use the one you already have.
The problem is, since the first parameter in the function definition has the @ sign in front of it, if you were to pass the pbPtr& var as the first paramter, the compiler would generate a pointer to your pointer and, to put it mildy, all hell would break loose.
In steps the = sign.
In order to use that pointer (pbPtr&) as the first parameter, you have to tell the compiler _not_ to automatically generate a pointer on the first parameter. The = sign does just that. It says that what you are passing as the first parameter _already_is_ a pointer, so don't automatically generate one.
This is a very sparsely-documented feature of FB, and requires some explanation.
If you want FB to pass a function parameter "by reference" instead of "by value," then you set up the parameter in the _formal_ parameter list (in the LOCAL FN statement) as a long integer variable preceded by the "@" symbol. This is what's done for LOCAL FN ListFolder:
LOCAL FN ListFolder (@pbPtr&, dirID&)
Setting it up this way means that, when you call this FN, FB expects you to use a "container" (a variable, an array element or a record) as the parameter, and FB will pass the _address_ of the container rather than the _contents_ of the container. And in fact, one of the statements in the demo code looks like this:
FN ListFolder (cInfoPBRec, 0)
cInfoPBRec is defined as a 128-byte record. Because of the way LOCAL FN ListFolder is declared, FB puts the _address_ of cInfoPBRec into pbPtr&, when the FN is called.
But sometimes, instead of passing the address of a _container_ into the pbPtr& parameter, you may wish to pass some arbitrary address--one that isn't the address of any container.
That's what the "=" notation is for. When you pass a parameter that is preceded by "=", FB expects a long-integer expression to follow the "=". It evaluates that expression, then passes the expression's value into the corresponding long-integer parameter inside the LOCAL FN. (This only applies to formal parameters that are set up as "by-reference" parameters; i.e. using the "@" symbol.) So:
FN ListFolder (cInfoPBRec, 0)
passes the _address_ of the cInfoPBRec record into the formal pbPtr& parameter, but:
FN ListFolder (=pbPtr&, pbPtr&.ioDirID&)
passes the _value_ of pbPtr& into the formal pbPtr& parameter.
So this is why we don't need to pass addresses to FB-defined Toolbox functions that normally require addresses as parameters.
For example,
Call SETRECT(theRect,0,0,10,10)
works properly because FB has implemented the call as
SETRECT(@theRect,l,t,r,b)
That's essentially correct. And there's a similar construction to the "=" syntax that works for such Toolbox calls, when you want to specify an arbitrary address (a pointer) rather than a "container." For Toolbox calls, you use "#". For example:
CALL SETRECT(#rectPtr&, 0, 0, 10, 10)
(For my money, things would be easier to remember if FB used a single symbol for "=" and "#", since the two perform virtually identical functions.)
Also remember that _some_ FB implementations of Toolbox calls _do_ expect you to specify a pointer rather than a container. (e.g. GETCATINFO(@pb), not GETCATINFO(pb)). It's sort of a matter of trial and error figuring out which convention FB has adopted for which routines.
|