I didn't get the original message, so I'm not sure if it's just for Delphi
that you're looking for a solution.... if it's for TP/BP, you can do it by
passing ALL the vaiable in a single string to the subroutine, then parse
it yourself inside the subroutine.
I do this. I chose the "|" character as a delimiter and call it like this:
CallingRoutine('param1|param2|param3|param4|...');
Inside the routine you can define either an array (and limit the number of
parameters to a finite number), or build a dynamic list for an indefinite
number.
PROCEDURE Callingroutine(InString : STRING);
VAR
index : BYTE; { loop index }
counter : BYTE; { parameter counter }
ParamList : ARRAY[1..20] OF STRING;{ parameter list }
BEGIN
FOR index := 1 TO 20 DO BEGIN
ParamList[index] := ''; { init the parameter list }
END;
counter := 1; { init the counter }
{ Go through each character and either add it to the current parameter }
{ or start a new parameter }
FOR index := 1 TO LENGTH(InString) DO BEGIN
IF InString[index] <> '|' THEN BEGIN
ParamList[counter] := ParamList[counter] + InString[index];
END
ELSE BEGIN
counter := counter + 1;
END;
END;
{ counter represents how many parameters were passed to the procedure }
{ and you can add the functionality of your subroutine from this point }
{ on. Here you can convert values to numeric, boolean or assign to }
{ a record or anything ... that is up to you. }
END;
Hope this is helpful (to someone, if not the original sender.)
Brian.
Another way of passing an unknown number of parameters (up to the
usual 64 K) can be done using typeless Var parameters :
Procedure SomeProc (Var Parameters; Size : Word);
Type
MyRec = Record
param1 : Integer;
param2 : Integer;
....
param_n : Integer;
End;
Var
MyList : MyRec ABSOLUTE Parameters;
Begin
WriteLn (MyList.param1);
WriteLn (MyList.param2);
....
WriteLn (MyList.param_n);
End;
Var
Buffer : Array [1..10] Of Integer;
Begin
FillChar (Buffer,20,0);
SomeProc (Buffer,10);
End.
This method does not consume much stack space as only a pointer
to the structure containing the parameters is passed to the procedure.
(so if a command like MyList.param1:=1; is executed in the procedure,
the value of Buffer[1] changes!).
My standard way to handle an unknown (at compile time) number of parameters in
BP was to use an untyped var parameter. This can then be viewed as a
substitute for the stack pointer that a standard fixed number call would
provide. Unfortunately the compiler is not going to do all the dereferencing
for you and so you do it yourself. The optimal method depends on the kinds of
arguments to be passed. The main kinds I have handled are:
1. Version structures - providing backward compatability. Here the first word
from the untyped parameter is always taken to be the length in bytes of the
parameter. Each version has a different length and the routine maps a pointer
of the appropriate version type to the parameter.
2. All the same type. Map a dynamic array of the appropriate type. There can
be an argument to specify the number of elements or and end-of-list indicator.
Packed strings are easily navigated using the length bytes.
3. Mixed types. Here the receiving process needs type information which I
passed as pairs of format numbers ("registered" types) and values, or the
format numbers can come first as an array followed by an array of values (the
latter is better if you are creating arrays for the received values).
The process can be turned into an object if one likes (I never got round to
that).
I have always regretted the lack of direct compiler support for
variable-number-of-arguments in Pascal, but perhaps forcing one to think about
optimization has some merits.
Perhaps Borland Object Pascal (Delphi & maybe BP8) could go further by
allowing run-time types to be passed with values ("typed" tag on function
declaration?) and have a standard NumArguments variable. However, I suspect
this would have a heavy cost in size and processing, especially for a one-pass
compiler. It's not my top priority for compiler enhancement.
There's no "starting with Delphi" to it. Anybody who wants to can do
this with TP 6.0, TP 7.0, BP 7.0, and probably with earlier versions of
Turbo Pascal as well.
Several of the standard TP/BP functions/procedure do this - and thus
gave hints to many of us a long time ago about how to do this.
On a slightly different tack - when your parameters are not all of the
same size (strings for example), a linked list of strings is a good way
to pass the parameters. Object oriented programming also makes it
practical to pass a linked list of objects so that the items in the list
don't even have to all be of the same type.
You must be confusing this with something else. Only Delphi
supports open arrays of const. TP/BP 7.0 and any earlier
versions don't.
> On a slightly different tack - when your parameters are not all of the
> same size (strings for example), a linked list of strings is a good way
> to pass the parameters. Object oriented programming also makes it
> practical to pass a linked list of objects so that the items in the list
> don't even have to all be of the same type.
With Delphis array of const, the parameters needn't have
the same length, and they even needn't be the same type.
Regards,
Oliver
--
Oliver Fromme, Leibnizstr. 18-61, 38678 Clausthal, Germany
BBS (TBH-BOX): +49-5323-5143 Internet email: fro...@rz.tu-clausthal.de
Info service: send email with Subject "SEND HELP" to the above address
FTP: ftp.tu-clausthal.de WWW: http://www.rz.tu-clausthal.de/~inof/
You can declare an argument of type: array of const
and pass the parameters the same way you pass them to procedures like
Format(), etc.
-- Bill Raike