I'd like to use procedure of object in a record, like so:
TCommandRec = record
name: string;
fn: procedure of object;
end;
I can create an array with this by assignment:
commands: array [0..1] of TCommandRec;
...
commands[0].name := '-help';
commands[0].fn := DoHelp;
commands[1].name := '-load';
commands[1].fn := DoLoad;
What I'd really like to do is declare a constant:
const
cmds: array [0..1] of TCommandRec =
(
(name: '-help'; fn: DoHelp),
(name: '-load'; fn: DoLoad)
);
However, I get errors for DoHelp and DoLoad - Constant expression expected. These are two methods of a class. Is there some syntax I need to use to make this work or am I stuck building the array at runtime?
A method of object is what is known as a two pointer type. It encapsulates the following information:
The former is known at compile time but generally the latter is not. Which is why you typically need to create these things at runtime.
If you can arrange that the subject is known at compile time then you can declare a typed constant of your record type. For example:
type
TMyRecord = record
Foo: procedure of object;
end;
TMyStaticClass = class
class procedure Foo;
end;
class procedure TMyStaticClass.Foo;
begin
end;
const
MyRecord: TMyRecord = (Foo: TMyStaticClass.Foo);
Of course, that's only going to be useful to you if your functions are viable as class methods rather than instance methods. I'm just adding the code above to illustrate that you can have constant method pointers, so long as the subject is a compile time constant.
You can store pointers to methods in your records (these are known at compile-time, so no problem specifying them in a const definition):
TCommandRec = record
name: string;
fn: Pointer;
end;
...
const
cmds: array [0..1] of TCommandRec =
(
(name: '-help'; fn: @DoHelp),
(name: '-load'; fn: @DoLoad)
);
Then, when you need to call fn
of cmds[i]
(I suppose that the call occurs inside the same class which defines the DoHelp
and DoLoad
methods), write something like:
type TObjectProc = procedure of object;
var m: TMethod;
...
m.Code := cmds[i].fn;
m.Data := Self;
TObjectProc(m);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With