How to dynamically create and pass an array of const?

This is a tough one for VCL and inline assembly gurus.

I need to dynamically create the Value parameter to pass to the Format function.  (Or rewrite Format's existing functionality - ugh)

Review of common knowledge:

Format has the following declaration:
  Function Format (const aFormat: String; const values: array of const);


The desired functionality is along the lines of:

function TMyRule.ResultString (fmt: String): String;
    Params := BuildParams;
    aString := Format (fmt, Params);

I have determined that the array of const is implemented as an array of TVarRec's.  I am uncertain about whether it is actually a variant array or not.  Either way, I can build it.  Any input?

BUT ... there is no syntactic model to pass the created array to the function.  The Pascal syntax only allows the array to be compiled in.

A review of the format function in SysUtils.pas suggests that it should be possible to write the call with an inline assembly call.  This is the real meat of the problem.  
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Well, at least in D5 you can do this:

type TVarRecArr = array of TVarRec;

function BuildParams : TVarRecArr;
  SetLength(result, 5);
  // here fill the array

  Format('test', BuildParams);

I think that should work for D4, too. For D2/3 you can perhaps do the same, but with this type declaration instead:

type TVarRecArr  = array [0..$FFFF] of TVarRec;
     TPVarRecArr = ^TVarRecArr;

function BuildParams : TPVarRecArr;
  result := AllocMem(sizeOf(TVarRecArr) * 5);
  // here fill the array

var params : TPVarRecArr;
  params := BuildParams;
    Format('test', params^);
  finally FreeMem(params) end;

Look also at "Slice".

Does this help?

Regards, Madshi.
dejohn99Author Commented:

I'll try this an let you know what happens.

I'm using D3.02 C/S.
Format's second parameter is what's called a variant open array .  This example, taken from the Delphi 4 help file, shows how to access it and build it up dynamically:
---From the Help ----
Variant open array parameters allow you to pass an array of differently-typed expressions to a single procedure or function. To define a routine with a variant open array parameter, specify array of const as the parameter’s type. Thus

procedure DoSomething(A: array of const);

declares a procedure called DoSomething that can operate on heterogeneous arrays.
The array of const construction is equivalent to array of TVarRec. TVarRec, declared in the System unit, represents a record with a variant part that can hold values of integer, Boolean, character, real, string, pointer, class, class reference, interface, and variant types. TVarRec’s VType field indicates the type of each element in the array. Some types are passed as pointers rather than values; in particular, long strings are passed as Pointer and must be typecast to string.

The following example uses a variant open array parameter in a function that creates a string representation of each element passed to it and concatenates the results into a single string. The string-handling routines called in this function are defined in SysUtils.

function MakeStr(const Args: array of const): string;

  BoolChars: array[Boolean] of Char = ('F', 'T');
  I: Integer;
  Result := '';
  for I := 0 to High(Args) do
    with Args[I] do
      case VType of
        vtInteger:    Result := Result + IntToStr(VInteger);
        vtBoolean:    Result := Result + BoolChars[VBoolean];
        vtChar:       Result := Result + VChar;
        vtExtended:   Result := Result + FloatToStr(VExtended^);

        vtString:     Result := Result + VString^;
        vtPChar:      Result := Result + VPChar;
        vtObject:     Result := Result + VObject.ClassName;
        vtClass:      Result := Result + VClass.ClassName;
        vtAnsiString: Result := Result + string(VAnsiString);
        vtCurrency:   Result := Result + CurrToStr(VCurrency^);
        vtVariant:    Result := Result + string(VVariant^);
        vtInt64:      Result := Result + IntToStr(VInt64^);


We can call this function using an open array constructor (see Open array constructors). For example,

MakeStr(['test', 100, ' ', True, 3.14159, TForm])

returns the string “test100 T3.14159TForm”.

--- End of the help file insert----

This is what you are looking for, I believe.

CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

dejohn99Author Commented:
Madshi:  Your solution worked perfectly.  Please submit as an answer for your points.  Thanks a million!

SBurck: Thanks for the info.  I must have been in a pre-christmas brain death when I read this the first time(it's exactly the same in the D3 help).  This is where I got the info I needed to build the structure in the first place.  Sigh.

BTW, in the meanwhile you can accept a comment as the answer (new EE feature)...

Regards, Madshi.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dejohn99Author Commented:
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.