"Carlos Saez" <carlo...@terra.es> wrote in message
news:3ec22dfe$2...@newsgroups.borland.com...
"Willo van der Merwe" <wi...@wack.co.za> escribió en el mensaje
news:3ec2...@newsgroups.borland.com...
You need a way to identify the procedure/method. One way is to use a symbol
table or a hash table where you associate the procedure name with a pointer.
You can do this by building a lookup table yourself or by using RTTI and
have the compiler build the lookup for you.
You also need a way to identify the numer and type of parameters the
procedure might expect and the return type, if it is a function.
The easiest is to identify a fixed number of procedures/methods/functions
you will likely use and define their type like so:
type
T0Function = function : integer; //Function taking 0 parameters and
returning an integer
T0Procedure = procedure; //Procedure taking 0 parameters
TABProcedure = procedure (A,B:integer); //Procedure taking 2 integer
parameters
Then define a constant to identify each type
const
fn0 = 0;
p0 = 1;
pab = 2;
and a type
type
TLookupRec = record
ProcName : string[20]; //function procedure name
ProcType : integer; //function type
ProcPtr : pointer; //function pointer
end;
some functions
function testfn : integer;
begin
Result := 100;
end;
procedure testp;
begin
{do something interresting}
end;
procedure testp2( A, B : integer );
begin
{do something interresting with A and B}
end;
lookup table
var
Lookup = array[0..2] of TLookupRec = (
(ProcName : 'testfn'; ProcType : fn0; ProcPtr : @testfn ),
(ProcName : 'testp'; ProcType : p0; ProcPtr : @testp ),
(ProcName : 'testp2'; ProcType : pab; ProcPtr : @testp2 ) );
the proc to invoke it:
procedure InvokeProc( Name : string );
var
Idx : integer;
begin
Idx := 0;
while Idx < 3 do
begin
if Lookup[Idx].ProcName = Name then
begin
case Lookup[Idx].ProcType of
fn0 : J := T0Function(Lookup[Idx].ProcPtr);
p0 : T0Procedure(Lookup[Idx].ProcPtr);
pab : TABProcedure(Lookup[Idx].ProcPtr)( A, B );
end;
end;
end;
end;
Hope this helps,
Willo
"Carlos Saez" <carlo...@terra.es> wrote in message
news:3ec23122$1...@newsgroups.borland.com...
procedure CommandLine;
Var
i : Integer;
begin
for i := 1 to ParamCount do
begin
if LowerCase(ParamStr(i)) = '-u' then
RunProcedure1;
if LowerCase(ParamStr(i)) = '-p' then
RunProcedure2;
end;
end;
eg. (Untested)
TStringList will not work for methods, as you'll need something that can
hold pairs of pointers.
type
TMyProc = procedure ....;
TProcedures = class
private
fProcs: TStringList;
public
procedure Register(ProcName: string; Proc: TMyProc);
procedure Call(ProcName: string; ...parameters... );
end;
var
Procedures : TProcedures ;
procedure TProcedures.Register(ProcName: string; Proc: TMyProc);
begin
fProcs.AddObject( ProcName, TObject(Proc) );
end;
procedure TProcedures.Call(ProcName: string; ...parameters... );
var
i : integer;
begin
i := IndexOf( ProcName )
TMyProc( fProcs.Objects[i] )(...parameters...);
end;
Something along this line is what I would generally do.
The only major downfall on this code was pushing floating numbers... if you do, stick with the "Extended" type and cast as needed... I *May* have workaround code laying around here, but it wasn't important to what I was doing, so I quit working on it.
SO, whenever someone tells you something isn't possible, tell them that *EVERYTHING* is possible if you think about it enough.
tinyURL:
Mike Johnson
www.bigattichouse.com
(is psuedo-code:)
TExecutionObject
Parameters[]:Variant or something like that
Execute / virtual;overload;
Execute:Variant / virtual;overload
Even better all the params and result types could be TField.
Now.. for each Type of procedure you wish to execute, you create an Execution Object..
TNotifyEventExecution=class(TExecutionObject)
property Event:TNotifyEvent
execute;override;
This can then call the assigne event.
You could build something like:
MyEventList.CreateExecutionObject (Button1.onclick,TNotifyEvent)
and later call it ...
let me know if you'd like help putting this together.
Oh, and you *CAN* get event types, I just have to remember how to find the info. (RTTI holds it, If my quickrtti project revealed)
I'll keep the procedure information in a list (in my case almost every unit
with a form adds a procedure to be call dinamycally, so all of them will be
added to the list in the Initialitation section of each respective unit).
As Michael Jhonson states, I also need to load packages dinamically and
execute procedures inside them (for showing and managing forms).
Although my need for passing parameters to the procedures are much more
simple, I won't forget the method proposed by MJ.
Regards,
Carlos.
"Carlos Saez" <carlo...@terra.es> escribió en el mensaje
news:3ec22dfe$2...@newsgroups.borland.com...