【问题标题】:function EXE to DLL (Delphi)函数 EXE 到 DLL (Delphi)
【发布时间】:2017-10-16 14:21:01
【问题描述】:

我正在调整我的应用程序以使用单独的模块(插件)。

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

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

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

function GetMemo(): widestring;

在我的想法中,任何编写 DLL 插件的人,在调用 函数 GetMemo() 时,都会在 DLL 中获取 TMemo 的内容。

有可能吗?

【问题讨论】:

  • 您的应用程序的使用者必须做很多工作。最好将您的表单放入 DLL 中。
  • 当然可以。可执行文件可以导出函数。不过,为插件提供 COM 接口可能会更好。用这么少的信息很难指导设计。
  • 要么使用 Delphi 原生类型并编写 BPL,就像 Delphi 本身编写的那样,要么坚持 Microsoft COM 标准,但它需要学习额外的工具,如外部类型(接口)定义

标签: delphi dll plugins export exe


【解决方案1】:

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

例如:

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;

【讨论】:

  • 请问,如何在 google 上搜索以了解有关此主题的更多信息?
  • 这个块 PPluginExeFunctions = ^MyFunctions; “MyFunction”是 GetMemo?
  • @André:这是一个错字,应该改成^PluginExeFunctions
【解决方案2】:
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 那样疯狂,在前面的代码中,添加一个加载库,它加载一个 DLL,实习生可以加载调用者的库。

我的意思是要表明,您的 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
  • 我知道,一个迟到的答案,但是,一个很好的问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多