Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-01

how to pass a procedure address and execute it?

12 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

waldo kitty

i'm trying to use one routine (centralControl) to process data from two different routines (inputThis and outputThat)... the one routine (centralControl) needs to call one of two other routines (doThis or doThat)... how? :(

procedure doThis;
begin
end;
procedure doThat;
begin
end;
procedure centralControl(var aValue : word; theRecord : somerec; var whichProc);
begin
   case aValue of
     0 : begin
           whichProc;   <<-- compiler says "illegal expression"
         end;
     1 : begin
           if theRecord^.aValue = something then
             whichProc;
         end;
end;
procedure inputThis;
begin
   centralControl(foo,thisRecord,@doThis);
end;
procedure outputThat;
begin
   centralControl(foo,thisRecord,@doThat);
end;
NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

Ewald
to waldo kitty
waldo kitty wrote
i'm trying to use one routine (centralControl) to process data from two different routines (inputThis and outputThat)... the one routine (centralControl) needs to call one of two other routines (doThis or doThat)... how? :(
First define a type to make your like easier:
Type
	TProcType: Procedure;
Next, adjust contralContol's prototype: procedure centralControl(var aValue : word; theRecord : somerec; whichProc: TProcType);

And you're done:-)

Ewald

Reply by email

Marco van de Voort
to waldo kitty: i'm trying to use one routine (centralControl) to process data from two different…

In our previous episode, waldo kitty said:

i'm trying to use one routine (centralControl) to process data from two different routines (inputThis and outputThat)... the one routine (centralControl) needs to call one of two other routines

whichproc is typeless and thus roughly equal to a pointer to a byte (though semantically different, and add another pointer indirection for the VAR). So the compiler doesn't know what to do with it.

how? :(

Define a procedure type that matches both procedures, in your example

Type
  TProc = procedure ; // which is predefined in system afaik.

and change whichproc to that type. The VAR is not necessary in this case.

Reply by email

Jim Leonard
to Marco van de Voort
Marco van de Voort wrote 6 lines
Define a procedure type that matches both procedures, in your example Type TProc = procedure ; // which is predefined in system afaik. and change whichproc to that type. The VAR is not necessary in this case.

Alternately, switch to an OOP model, whose entire model (inheritance) addresses this sort of thing.

Jim Leonard () Check out some trippy MindCandy: http://www.mindcandydvd.com/ A child borne of the home computer wars: http://trixter.oldskool.org/ You're all insane and trying to steal my magic bag!

Reply by email

waldo kitty
to Ewald: First define a type to make your like easier: Type TProcType: Procedure; Next, adjust…
Ewald wrote 17 lines
On 23 Jan 2014, at 20:18, waldo kitty wrote: > > i'm trying to use one routine (centralControl) to process data from two > different routines (inputThis and outputThat)... the one routine > (centralControl) needs to call one of two other routines (doThis or doThat)... > how? :( > First define a type to make your like easier: Type TProcType: Procedure; Next, adjust contralContol's prototype: procedure centralControl(var aValue : word; theRecord : somerec; whichProc: TProcType); And you're done:-)

damn! i was so close so many times! i did try using "pointer" as the type with and without 'var' for whichProc... this will be a huge savings in time and code size! thanks!

NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

waldo kitty
to Marco van de Voort: In our previous episode, waldo kitty said: whichproc is typeless and thus roughly equal…
Marco van de Voort wrote 18 lines
In our previous episode, waldo kitty said: > > i'm trying to use one routine (centralControl) to process data from two > different routines (inputThis and outputThat)... the one routine > (centralControl) needs to call one of two other routines whichproc is typeless and thus roughly equal to a pointer to a byte (though semantically different, and add another pointer indirection for the VAR). So the compiler doesn't know what to do with it. > how? :( Define a procedure type that matches both procedures, in your example Type TProc = procedure ; // which is predefined in system afaik. and change whichproc to that type. The VAR is not necessary in this case.

excellent! as noted in a previous post, i was so close several times ;)

NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

waldo kitty
to Jim Leonard: Alternately, switch to an OOP model, whose entire model (inheritance) addresses this sort…
Jim Leonard wrote 10 lines
On 1/23/2014 1:27 PM, Marco van de Voort wrote: > Define a procedure type that matches both procedures, in your example > > Type > TProc = procedure ; // which is predefined in system afaik. > > and change whichproc to that type. The VAR is not necessary in this case. Alternately, switch to an OOP model, whose entire model (inheritance) addresses this sort of thing.

interesting... i do use customapplication for the main program so i can take advantage of getoption and friends... i wonder... hummm...

NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

Ewald
to waldo kitty: following up on this, how do i pass parameters to doThis and doThat?? do i have to use an…
waldo kitty wrote
On 1/23/2014 2:18 PM, waldo kitty wrote: following up on this, how do i pass parameters to doThis and doThat?? do i have to use an intermediate pre_doThis and pre_doThat which handles the calls from centralControl and then calls doThis and doThat with the necessary parameters?
Simply change the type:
	Type
		TProc = Procedure(aRecord: somerec);

Then you can call whichProc (in centralControl) with your argument of choice.

Ewald

Reply by email

waldo kitty
to waldo kitty: i'm trying to use one routine (centralControl) to process data from two different…

On 1/23/2014 2:18 PM, waldo kitty wrote:

following up on this, how do i pass parameters to doThis and doThat?? do i have to use an intermediate pre_doThis and pre_doThat which handles the calls from centralControl and then calls doThis and doThat with the necessary parameters?

type
   TProc = Procedure;
procedure doThis(aRecord : somerec;);
begin
   addRecord(aRecord);
end;
procedure doThat(outFile : textfile; aRecord : somerec;);
begin
   writefile(outFile,aRecord);
end;
procedure pre_doThis;
begin
   doThis(theRecord);
end;
procedure pre_doThat;
begin
   doThat(oFile,theRecord);
end;
procedure centralControl(var aValue : word; theRecord : somerec; whichProc : TProc);
begin
   case aValue of
     0 : begin
           whichProc;
         end;
     1 : begin
           if theRecord^.aValue = something then
             whichProc;
         end;
end;
procedure inputThis;
begin
   centralControl(foo,thisRecord,@pre_doThis);
end;
procedure outputThat;
begin
   centralControl(foo,thisRecord,@pre_doThat);
end;
NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

waldo kitty
to Ewald: Simply change the type: Type TProc = Procedure(aRecord: somerec); Then you can call…
Ewald wrote 15 lines
On 24 Jan 2014, at 21:20, waldo kitty wrote: > On 1/23/2014 2:18 PM, waldo kitty wrote: > > following up on this, how do i pass parameters to doThis and doThat?? do i > have to use an intermediate pre_doThis and pre_doThat which handles the calls > from centralControl and then calls doThis and doThat with the necessary parameters? > Simply change the type: Type TProc = Procedure(aRecord: somerec); Then you can call whichProc (in centralControl) with your argument of choice.

ahhh! that helps to explain what the compiler error was that i was seeing... so i may need two different types if each procedure called from centralControl has different parameters? won't that cause a conflict if the parameters are not the same or are in different ordering or even if some procedure doesn't have parameters at all?

NOTE: No off-list assistance is given without prior approval. Please keep mailing list traffic on the list unless private contact is specifically requested and granted.

Reply by email

Ewald
to waldo kitty
waldo kitty wrote 18 lines
On 1/24/2014 3:18 PM, Ewald wrote: > > On 24 Jan 2014, at 21:20, waldo kitty wrote: > >> On 1/23/2014 2:18 PM, waldo kitty wrote: >> >> following up on this, how do i pass parameters to doThis and doThat?? do i >> have to use an intermediate pre_doThis and pre_doThat which handles the calls >> from centralControl and then calls doThis and doThat with the necessary parameters? >> > > Simply change the type: > Type > TProc = Procedure(aRecord: somerec); > > Then you can call whichProc (in centralControl) with your argument of choice. ahhh! that helps to explain what the compiler error was that i was seeing... so i may need two different types if each procedure called from centralControl has different parameters?

Basically yes (if you mean different parameter types/ different parameter order -- the name in the procedure/function type is merely descriptive AFAIK). But if you have many procedures, I'd go for a class:

TCentralControl = Class
Protected
	Procedure Callback1; virtual; abstract;
	Procedure Callback2(value: TSomeRec); virtual; abstract;
	Function Callback3: Boolean; virtual abstract;
	... and so on ...
Public
	Procedure CentralControl(.....);
End;

Then simply inherit from this class a few times for the different scenario's you want to cover.

won't that cause a conflict if the parameters are not the same or are in different ordering or even if some procedure doesn't have parameters at all?

Yes, you would need a lot of parameters if you need a lot of callbacks. if this is the case go for the OOP approach; it is perfectly suited for this kind of thing.

Ewald

Reply by email

leledumbo
to waldo kitty: ahhh! that helps to explain what the compiler error was that i was seeing... so i may…
ahhh! that helps to explain what the compiler error was that i was

seeing... so
i may need two different types if each procedure called from centralControl has
different parameters? won't that cause a conflict if the parameters are not the
same or are in different ordering or even if some procedure doesn't have parameters at all?

Yes, of course. If you want to implement something like callback, the parameters have to be consistent. You can't pass arbitrary procedure as it would violate the type safe property. One idea would be to have all possible procedures implement the same parameter list, but only use some of them in the implementation. This could slow down the processing a bit but if speed is not really an issue I don't think you should care.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/how-to-pass-a-procedure-address-and-execute-it-tp5718103p5718117.html Sent from the Free Pascal - General mailing list .

Reply by email