程序使用的程序和dll(都是在Delphi上编写的,代码都可以访问)。 在程序中有一个程序X,它根据来自dll的程序Y的询问推断出一些统计数据(在计时器上)。 程序Y在dll中发生某些事件时变得更加活跃,这可能在不同的时间间隔内出现。
问题:是否可以在dll中传输名称程序X,并在程序Y中执行它,以便立即了解发生的事件,而不是在计时器上查询它。 再次(或作为变体):如何在程序中定义,dll中有什么事件并执行过程X的代码? 如果可能的话,代码示例。
答案 0 :(得分:7)
如果我正确理解你的问题,你在EXE中有一些代码,在DLL中有一些代码。每隔一段时间,一个计时器就会触发,这会导致某些东西在其他方面进行轮询(不清楚谁在轮询什么),以查看一方是否有任何工作可用,而另一方的代码可以处理。并且您希望有一种方法让一方在工作可用时立即通知另一方,而不必等待计时器。
有一种非常成熟的方法可以做到这一点。在Delphi中设置它的标准习惯是使用事件和事件处理程序。这是基本的想法:
让我们调用创建数据的一方发布者,以及处理消费者工作的一方。为Publisher对象提供类型为TNotifyEvent
的变量。这在Classes
单位中声明为
TNotifyEvent = procedure(Sender: TObject) of object;
如果看起来很熟悉,那是因为很大比例的VCL事件处理程序(例如TButton.OnClick
)属于TNotifyEvent
类型。如果要在事件中传递更多有用的数据,则可以声明自己的事件类型。例如:
TDataReadyEvent = procedure(data: TStatisticalData) of object;
将事件处理程序类型的变量放在发布服务器(FOnDataReady: TDataReadyEvent;
)上,并创建一个公开它的属性。然后添加一些代码来触发事件。在Producer的某个地方,您有代码可以生成要分析的新数据。在完成之后,添加如下内容:
if assigned(FOnDataReady) then
FOnDataReady(NewData);
然后,在Consumer上,创建一个签名与事件处理程序类型匹配的方法。它应该能够处理数据。要将它们链接在一起,请在Consumer的初始化代码中执行类似的操作:
Producer.OnDataReady := self.HandleDataReady;
你有它!这真的很简单。现在,无论何时可以从Producer获得新数据,都会自动调用您的Consumer,而无需使用计时器并不断轮询Producer,询问它是否还有任何内容。
答案 1 :(得分:2)
在主模块和DLL中声明一个过程类型:
type
TMyCallbackProc = procedure(parameters);
将TMyCallbackProc
类型的参数添加到Y
程序的标题中:
procedure Y(const CallBackProc: TMyCallbackProc; other parameters as needed);
Y
过程正文中的某处添加对所述参数过程的调用:
…
CallBackProc(arguments);
…
从主应用程序调用{{1}}过程时,根据Y的声明传递Y
过程:
X