开发者

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

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 i开发者_开发知识库t is possible, a code example.


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.


  1. Declare a procedural type both in your main module and in the DLL:

    type
      TMyCallbackProc = procedure(parameters);
    
  2. Add a parameter of the TMyCallbackProc type to the Y procedure's header:

    procedure Y(const CallBackProc: TMyCallbackProc; other parameters as needed);
    
  3. Somewhere in the body of the Y procedure add the call to the said parameter procedure:

    …
    CallBackProc(arguments);
    …
    
  4. When invoking the Y procedure from the main application, pass the X procedure according to Y's declaration:

    …
    Y(X, other arguments);
    …
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜