?
Solved

some sort of procedure pointer...dunno if this is possible though...

Posted on 2003-03-14
8
Medium Priority
?
161 Views
Last Modified: 2010-04-04
Hiya all!

Here's the setup that I've got:

Unit1

func1
func2
func3
funcdo


Unit2

func1
func2
func3



In fact I've got LOADS more functions in unit1 and unit2 but I'd need to make a new post just to list them all :) But only one 'funcdo'. What is currently happening is:

1) a function in unit1 is ran (but not funcdo just yet) and sets a global variable
2) this keeps happening based on what the user does
3) eventually funcdo is called
4) funcdo uses a switch statement and goes through all of the values of the gobal variable that could be assigned to it
5) It then calls the appropriate function in unit2

As I've said I've got LOADS (over 70+) functions in both unit1 and unit2 each. What I'm wanting is for each function in unit1 (not funcdo) to set a pointer or something to the function that would needed to be called in unit2. Then when funcdo is ran it actually calls that function using the pointer. The problem though is that many of the functions don't have the same number or type of arguments as that seems to have been the requirement to do what I want to do.


Can anybody give me a bit of a shove in the right direction? :)

Thanks
NAE
0
Comment
Question by:nearlyanexpert
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 9

Expert Comment

by:mocarts
ID: 8139208
you can use unit name prefix to explicitly tell compiler which function to call:

Result := unit2.func1(params);

wbr, mo.
0
 
LVL 6

Expert Comment

by:zebada
ID: 8139255
If your functions all have the same return type, you can declare them with an arg list of "array of const" as follows:

You can then use the same "function pointer type" variable to reference any of your 70+ functions.

TGenericFunction = function(vargs: array of const): integer;

...

// These functions are from your unit2
function func2a(vargs: array of const): integer;
begin
  Result := vargs[0].VInteger;
end;

function func2b(vargs: array of const): integer;
begin
  Result := vargs[0].VInteger*vargs[1].VInteger;
end;

This represents your "funcdo" function:
procedure TForm1.Button1Click(Sender: TObject);
var
  fa,fb: TGenericFunction;
begin
  // You would need to decide which function to call and what parameters to pass to it here.
// I've just show an exampole of calling both functions.
  fa := func2a;
  fb := func2b;
  ShowMessage(Format('Func1=%d Func2=%d',[fa([10]),fb([10,20])]));
end;

There may be a more elegant way but this is the only way I know to do it.
If all your functions have the same argument list then you would declare that argument list instead of "array of const".

Regards
Paul
0
 

Author Comment

by:nearlyanexpert
ID: 8140243
Darn....my fault, its not a function at all I'm needing its a procedure pointer :(. None of the functions in anything return a value...

mocarts, I'm aware of that, although I know what I need to do but just don't know how to do it.

zebada, yeah summit like that, although I got mixed up with function and procedure :(. Although in the,

TGenericFunction = function(vargs: array of const): integer;

What does the ": integer;" mean at the end? Is that the return type or something? What would I put if nothing was returned at all?


Here's how a couple of things are declared:


Unit1

procedure Tfrmmain.btn1Click(Sender: TObject);
begin
   //I want to set some global pointer thingy to the procedure func2 in Unit2
end;

procedure funcdo;
begin
   // run the pointer procedure thingy
end;



Unit2

procedure func2(restriction: String);
begin
   //daft stuff done
end;



Dunno if that has made things better.

NAE
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:nearlyanexpert
ID: 8140430
hmm...I've sorta figured it out, however I want:


TGenericFunction = function(vargs: array of const): integer;

available to just this unit. The things like:


fa,fb: TGenericFunction

I want available also to just unit also, so that when a few buttons are pressed each one is able to set fa to a different procedure, and then when a certain button is pressed the procedure that is assigned to fa is called.

That's it.

Thanks again,
NAE
0
 

Author Comment

by:nearlyanexpert
ID: 8140441
btw I've tried the following:


(just under the Unit1 public section)

var
  frmmain: Tfrmmain;
    Genprocedure : procedure(Const S: array of Char);
    filter_producer_call : Genprocedure;


But I get a "constant or type identifier expected" error...


NAE
0
 
LVL 6

Accepted Solution

by:
zebada earned 400 total points
ID: 8140923
Here's the "other" unit containing the functions:
unit Unit1;

interface

uses
  SysUtils,Dialogs;

procedure proc1(vargs: array of variant);
procedure proc2(vargs: array of variant);

implementation

procedure proc1(vargs: array of variant);
begin
  ShowMessage(Format('Proc1: arg1=%d',[Integer(vargs[0])]));
end;

procedure proc2(vargs: array of variant);
begin
  ShowMessage(Format('Proc2: arg1=%d arg2=%d',[Integer(vargs[0]),Integer(vargs[1])]));
end;

end.


Here's the main form with 3 buttons:

unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TGenericProcedure = procedure(args: array of variant);

  TForm1 = class(TForm)
    btnProc1: TButton;
    btnProc2: TButton;
    btnDoit: TButton;
    procedure btnProc1Click(Sender: TObject);
    procedure btnProc2Click(Sender: TObject);
    procedure btnDoitClick(Sender: TObject);
  private
    { Private declarations }
    proc: TGenericProcedure;
    args: array of variant;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

Uses
  Unit1;

{$R *.dfm}


procedure TForm1.btnProc1Click(Sender: TObject);
begin
  proc := proc1;
  args := VarArrayOf([10]);
end;

procedure TForm1.btnProc2Click(Sender: TObject);
begin
  proc := proc2;
  args := VarArrayOf([10,20]);
end;

procedure TForm1.btnDoitClick(Sender: TObject);
begin
  proc(args);
end;

end.

0
 
LVL 6

Expert Comment

by:zebada
ID: 8140928
You should also change the call to the proc to this:

procedure TForm1.btnDoitClick(Sender: TObject);
begin
  if ( assigned(proc) ) then
    proc(args);
end;

Otherwise if you call proc when proc is nil it will give an memory fault error.

0
 

Author Comment

by:nearlyanexpert
ID: 8143048
Thank you!


NAE
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Suggested Courses
Course of the Month9 days, 8 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question