【问题标题】:How can I pass TForm to a DLL as parameter?如何将 TForm 作为参数传递给 DLL?
【发布时间】:2013-03-02 14:39:18
【问题描述】:

我想制作使用 tform 作为参数的 dll,简单的计划是如果该表单传递给 dll,则 dll 文件返回包含组件名称的数组。

可以将 tform 作为参数传递吗?

【问题讨论】:

    标签: forms delphi dll


    【解决方案1】:

    您的进程中很可能会有两个 VCL 实例,一个用于主机 exe,一个用于 DLL。这是一个太多的例子。宿主 exe 中的 TForm 类与 DLL 中的 TForm 类不同。

    基本规则是您不能跨模块边界共享 VCL/RTL 对象,除非所有模块都使用相同的 VCL/RTL 运行时实例。实现这一点的方法是使用包链接到 VCL/RTL。

    【讨论】:

    • 嗨,大卫,作为我的问题,我的 dll 让组件列表正常工作,但如果我用“as”Tsomecomponent 分配组件,我会出错。我仍然对此感到困惑
    【解决方案2】:

    我假设你有一个框架,你的表单上有一个 TMemo:

    声明两种类型:

    type
      PTform                                  = ^TForm;
      TStringArray                            = array of string;
    

    并使这些对 EXE 和 DLL 可见

    .DPR 实施部分:

    procedure dllcomplist(p_pt_form : PTForm;
                      var p_tx_component : TStringArray);
              stdcall;
              external 'dllname.dll';
    

    ...

    var
      t_tx_component                          : TStringArray;
      t_ix_component                          : integer;
    

    ...

      Memo1.Lines.Add('Call DLL to return componentlist');
      dllcomplist(pt_form,t_tx_component);
      Memo1.Lines.Add('Result in main program');
      for t_ix_component := 0 to pred(length(t_tx_component)) do
        Memo1.Lines.Add(inttostr(t_ix_component) + '=' + t_tx_component[t_ix_component]);
      setlength(t_tx_component,0);
    

    在 DLL 的 .DPR 中

    ...

    procedure dllcomplist(p_pt_form : PTForm;
                      var p_tx_component : TStringArray);
              stdcall;
    var
      t_ix_component                          : integer;
      t_ix_memo                               : integer;
      t_tx_component                          : TStringArray;
    begin with p_pt_form^ do begin
      setlength(t_tx_component,componentcount);
      setlength(p_tx_component,componentcount);
      for t_ix_component := 0 to pred(componentcount) do
      begin
        t_tx_component[t_ix_component] := components[t_ix_component].Name;
        p_tx_component[t_ix_component] := components[t_ix_component].Name;
        if components[t_ix_component].ClassName = 'TMemo' then
          t_ix_memo := t_ix_component;
      end;
      Tmemo(components[t_ix_memo]).lines.add('Within DLL...');
      for t_ix_component := 0 to pred(componentcount) do
        Tmemo(components[t_ix_memo]).lines.add(inttostr(t_ix_component) + ' ' 
                + t_tx_component[t_ix_component]);
      Tmemo(components[t_ix_memo]).lines.add('DLL...Done');
      setlength(t_tx_component,0);
    end;
    end;
    

    ...

    exports dllcomplist;
    

    {好吧 - 这比严格需要的要复杂得多。我正在做的是在调用程序中建立一个动态数组,将其填充到 DLL 中,然后在调用者中显示结果

    检测 DLL 中的 TMemo 并将数据从 DLL 中的相同动态数组写入调用方的 TMemo - 以显示数据相同}

    【讨论】:

    • 您没有解决 DLL.TForm 与 EXE.TForm 不同的事实。这是无法克服的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多