【问题标题】:Delphi DLL / Form communicationDelphi DLL / 表单通讯
【发布时间】:2010-09-27 18:19:32
【问题描述】:

我在 DLL 中嵌入了一个表单,可以调用 DLL 并显示表单并将 DLL 中的各种函数返回到主应用程序,但是我不知道如何让 DLL 触发主应用程序中的事件形式。

例如,在主应用程序中,我有一个数据集,我想在 DLL 中的表单上有一个按钮来转到数据集中的某个记录,但看不到这是如何完成的。

谁能给我举个例子或给我一些关于如何做到这一点的指示?

【问题讨论】:

    标签: delphi dll


    【解决方案1】:

    如果 DLL 需要调用宿主应用程序中的行为,则宿主应向 DLL 提供 回调函数,该 DLL 存储并在适当时调用。

    您的 DLL 导出一个函数,告诉它显示表单,对吗?向该函数添加几个参数,以便 EXE 提供指向回调函数的指针。回调函数应至少接受一个参数,其类型应为Pointer。调用者(EXE)将使用该参数作为上下文参数,以某种方式提醒它为什么DLL调用EXE的函数。您的 DLL 将存储函数指针和上下文指针,当 DLL 需要告诉 EXE 某些内容时,它将调用该函数并将上下文值传回。 DLL 不会对上下文值做任何事情;它只是存储并逐字传递给 EXE 的东西。

    DLL 的界面如下所示:

    type
      TDllCallback = function(Context: Pointer): DWord; stdcall;
    
    function DisplayForm(Parent: HWnd; Callback: TDllCallback; Context: Pointer): DWord; stdcall; external Dll;
    

    EXE 会这样定义一个回调函数:

    function CallbackFunction(Context: Pointer): DWord; stdcall;
    begin
      TMainForm(Context).DoSomething;
      Result := 0;
    end;
    

    它会像这样调用 DLL 函数:

    procedure TMainForm.DoDllTaskClick(Sender: TObject);
    begin
      DisplayForm(Handle, CallbackFunction, Pointer(Self));
    end;
    

    注意CallbackFunction 的签名如何匹配前面定义的TDllcallback 类型。它们都使用 stdcall 调用约定,并且它们都是独立函数,而不是方法。避免使用方法,因为方法指针是 Delphi 特有的,如果可能的话,您不应该要求您的 DLL 仅由 Delphi 主机使用。

    【讨论】:

    • 并避免可能包含 IS 的代码,因为 DLL 上下文中的 IS 可能会产生与主程序不同的结果。
    • 使用is 运算符的代码很好,只要您在来自同一模块的对象上使用它。不仅仅是is 不应该跨越模块边界。最终,每个模块都应该被编写成好像没有其他模块知道什么是 Delphi 数据类型——不要共享任何类的对象。假设项目中的其他所有内容都是用 C 编写的。
    • 另一种方法是使用 BPL。这将使您的表单也可以使用全局 Application 对象,这有助于某些表单行为。
    • 通读以上是否意味着我只能使用回调方法向DLL中添加1个函数?
    • 当然不是,@User。您可以拥有任意数量的。您可以将它们全部作为不同的参数传递,或者您可以一次一个地依次传递它们。您甚至可以制作一个记录结构并将它们一起传递。一旦你有了记录,你就更接近于使用界面了。
    【解决方案2】:

    因为 DLL 的代码在主应用程序的同一地址空间中执行,所以有很多通信方式。

    1. 在主应用程序中定义一个回调函数并将其地址提供给 DLL。
    2. 在主应用程序中定义消息处理程序并从 DLL 发送消息以响应某些事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多