代码之家  ›  专栏  ›  技术社区  ›  André

函数EXE到DLL(Delphi)

  •  2
  • André  · 技术社区  · 7 年前

    我已经成功地使我的EXE应用程序读取和加载插件,包括表单。

    现在我需要做相反的事情,将函数从可执行文件导出到DLL。

    例子: 在我的可执行文件中,它有一个TMemo组件。我想创建一个这样的函数

    function GetMemo(): widestring;
    

    在我看来,无论是谁编写了DLL插件,当调用 ,将已经在DLL中获取TMemo的内容。

    有可能吗?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Remy Lebeau    7 年前

    最简单的处理方法是定义函数指针的记录,然后让EXE在初始化时将该记录的实例传递给每个插件。然后,EXE可以根据需要实现这些函数并将其传递给插件,而不需要像DLL那样从其PE exports表中实际导出它们。

    例如:

    type
      PPluginExeFunctions = ^PluginExeFunctions;
      PluginExeFunctions = record
        GetMemo: function: WideString; stdcall;
       ...
      end;
    

    function MyGetMemoFunc: WideString; stdcall;
    begin
      Result := Form1.Memo1.Text;
    end;
    
    ...
    
    var
      ExeFuncs: PluginExeFunctions;
      hPlugin: THandle;
      InitFunc: procedure(ExeFuncs: PPluginExeFunctions); stdcall;
    begin
      ExeFuncs.GetMemo := @MyGetMemoFunc;
      ...
      hPlugin := LoadLibrary('plugin.dll');
      @InitFunc := GetProcAddress(hPlugin, 'InitializePlugin');
      InitFunc(@ExeFuncs);
      ...
    end;
    

    var
      ExeFuncs: PluginExeFunctions;
    
    procedure InitializePlugin(pExeFuncs: PPluginExeFunctions); stdcall;
    begin
      ExeFuncs := pExeFuncs^;
    end;
    
    procedure DoSomething;
    var
      S: WideString;
    begin
      S := ExeFuncs.GetMemo();
      ...
    end;
    
        2
  •  0
  •   Ozz Nixon    4 年前
    unit uDoingExport;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;
    
    type
      TForm1 = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    procedure testproc; stdcall;
    
    implementation
    
    {$R *.dfm}
    
    procedure testproc;
    begin
       ShowMessage('testproc');
    End;
    
    exports
       testproc;
    
    end.
    

    我只是简单地在单元的界面中添加了我想从EXE中发布的方法,并在实现中添加了导出(方法名称)。我使用的是stdcall而不是cdecl。

    在我的孩子,我可以加载库的exe文件。。。或者你可以像Apache一样疯狂,在前面的代码中,添加一个loadlibrary,它加载一个DLL,intern可以加载调用程序的loadlibrary。

    我的意思是,你的EXE就像一个DLL(只是一个不同的二进制头),反之亦然。只是拍打出口。为了证明它有效,我对EXE运行了tdump:

    Exports from ProjDoingExport.exe
      1 exported name(s), 1 export addresse(s).  Ordinal base is 1.
      Sorted by Name:
        RVA      Ord. Hint Name
        -------- ---- ---- ----
        0005294C    1 0000 testproc
    
    • 我知道,一个迟来的回答,但是,一个很棒的问题!