Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To transfer in dll a name of procedure from the basic program and to execute it there

Tags:

dll

delphi

There is a program and dll which the program uses (both are written on Delphi and the code both is accessible). In the program there is a procedure X, which deduces some statistics (on the timer), on the basis of interrogation of procedure Y from dll. Procedure Y becomes more active at occurrence of some event in dll which can arise in different time intervals.

Question: whether it is possible to transfer in dll a name procedures X, and to execute it in procedure Y, to learn about arising events at once, instead of interrogating it on the timer. Once again (or as a variant): how in the program to define, what in dll there was an event and to execute a code of procedure X? If it is possible, a code example.

like image 791
Gu. Avatar asked Jan 20 '23 13:01

Gu.


1 Answers

If I understand your problem correctly, you've some code in an EXE and some more in a DLL. Every so often, a timer fires, which causes something to poll something else (not really clear on who's polling what) to see if any work is available on one side, which the code on the other side can process. And you'd like to have a way for the one side inform the other side immediately when work is available, instead of having to wait on a timer.

There's a pretty well-established way to do this. The standard idiom to set this up in Delphi is with an event and an event handler. Here's the basic idea:

Let's call the side that creates the data the Publisher, and the side that processes the work the Consumer. Give the Publisher object a variable of type TNotifyEvent. This is declared in the Classes unit as

TNotifyEvent = procedure(Sender: TObject) of object;

If that looks familiar, it's because a good percentage of VCL event handlers, such as TButton.OnClick, are of type TNotifyEvent. If you want to pass some more useful data in the event, you can declare your own event type instead. For example:

TDataReadyEvent = procedure(data: TStatisticalData) of object;

Put a variable of your event handler type on the Publisher (FOnDataReady: TDataReadyEvent;) and create a property that exposes it. Then add some code to fire the event. Somewhere in the Producer, you have code that produces new data to be analyzed. Right after that finishes, add something like this:

if assigned(FOnDataReady) then
  FOnDataReady(NewData);

Then, on the Consumer, create a method whose signature matches the event handler type. It should be able to process the data. To link them together, do something like this in your initialization code for the Consumer:

Producer.OnDataReady := self.HandleDataReady;

And there you have it! It's really that simple. Now your Consumer will be automatically invoked whenever new data is available from the Producer, without having to use a timer and continually poll the Producer asking if it's got anything yet.

like image 60
Mason Wheeler Avatar answered Feb 21 '23 15:02

Mason Wheeler