You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi 11开发的DLL中调用主应用程序的过程

实现DLL调用主应用程序过程的Delphi 11示例

核心思路是主应用程序将自身过程的地址传递给DLL,DLL通过保存的地址调用主程序的过程。下面是具体实现步骤:

1. 定义共享的过程类型

新建一个公共单元(比如SharedTypes.pas),主程序和DLL都要引用这个单元,用来定义和主程序过程匹配的函数类型:

unit SharedTypes;

interface

type
  TDrawRectangleProc = procedure(X, Y, W, H: Integer); stdcall; // 调用约定要和主程序保持一致

implementation

end.

2. 主应用程序端实现

主程序的目标过程实现

保留你原有的过程逻辑,补充调用约定声明:

procedure DrawRectangle(X, Y, W, H: Integer); stdcall;
var
  MyRect: TRectangle;
begin
  MyRect := TRectangle.Create(MainForm);
  MyRect.Position.X := X;
  MyRect.Position.Y := Y;
  MyRect.Width := W;
  MyRect.Height := H;
  MyRect.Parent := MainForm;
  // 其他绘制逻辑...
end;

主程序加载DLL并传递过程地址

主程序需要加载DLL,然后调用DLL导出的注册函数,把DrawRectangle的地址传递给DLL:

var
  DLLHandle: THandle; // 全局变量,用于后续释放DLL

procedure TMainForm.FormCreate(Sender: TObject);
type
  TRegisterDrawProc = procedure(DrawProc: TDrawRectangleProc); stdcall;
var
  RegisterDrawProc: TRegisterDrawProc;
begin
  DLLHandle := LoadLibrary('YourDLL.dll'); // 替换为你的DLL文件名
  if DLLHandle <> 0 then
  begin
    @RegisterDrawProc := GetProcAddress(DLLHandle, 'RegisterDrawRectangle');
    if Assigned(RegisterDrawProc) then
    begin
      RegisterDrawProc(DrawRectangle); // 将主程序过程地址传给DLL
    end;
  end;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  if DLLHandle <> 0 then
    FreeLibrary(DLLHandle);
end;

3. DLL端实现

DLL保存主程序过程地址并实现调用逻辑

DLL需要导出注册函数来接收主程序传递的地址,之后就可以在内部调用该过程:

library YourDLL;

uses
  SysUtils, Classes, SharedTypes;

{$R *.res}

var
  FDrawRectangle: TDrawRectangleProc; // 保存主程序过程的地址

// 导出给主程序调用的注册函数
procedure RegisterDrawRectangle(DrawProc: TDrawRectangleProc); stdcall;
begin
  FDrawRectangle := DrawProc;
end;

// DLL内部调用主程序过程的示例(也可导出该函数,让主程序主动触发调用)
procedure CallMainDrawLogic; stdcall;
begin
  if Assigned(FDrawRectangle) then
    FDrawRectangle(10, 10, 100, 100); // 调用主程序的DrawRectangle
end;

exports
  RegisterDrawRectangle,
  CallMainDrawLogic; // 可选导出,供主程序触发调用

begin
  FDrawRectangle := nil;
end.

关键注意事项

  • 必须保证调用约定完全一致(示例中统一用stdcall),否则会引发栈溢出或内存错误。
  • 公共单元的函数类型定义,参数数量、类型、顺序必须和主程序过程完全匹配。
  • 主程序要确保在DLL完成所有调用后再释放DLL,避免出现无效地址访问。

内容的提问来源于stack exchange,提问作者Mick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:00:20