Delphi中包(Package)的使用

本文介绍了一种在Delphi中动态加载Package并使用其中类、函数等资源的方法。通过创建代理包来解决单元冲突问题,并提供了注册、查找类实例的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Delphi中Package是一件非常强大的工具,用的好可以起到非常清晰的划分程序结构的作用。

因为他内建描述信息,可以和当前代码无缝集成起来,可以保护包括类在内的任何元素,相当于VC中的MFC Extension DLL的作用。

但是一直以来的文章都只介绍静态连接的方法,这其实限制了Package的使用因为静态连接的Package失去了其灵活性,可配置性等等。

至于通过函数入口方式访问,实在是大材小用,那不如直接用DLL还方便一些。  

如何动态载入Package,使用其中的类、函数、变量等等?

起始说穿了很简单,就是做一个代理包。因为在一个Delphi程序中,每个unit只能存在一份,否则发生冲突。要动态载入包,又得取得其中信息,又不能直接uses包含信息的unit(否则引起冲突),解决办法是另外建一个代理包来作为桥梁传递信息。

下面是一个简单的例子,主程序使用到两个包,

DemoPak包中有一个简单的Form;

RegPak是所谓的代理包,起到注册信息的作用。

主程序对RegPak静态使用(在Project Options里面设置了),对DemoPak动态载入(通过LoadPackage),而DemoPak依赖于RegPak(requires),并在初始化时向代理包RegPak注册自己的可用类,这里举例注册类信息,你可以方便的改成注册其他信息

unit FormReg;

interface

uses  Classes, SysUtils, Forms, Contnrs;

type  TFormClass = class of TForm;

procedure RegisterFormClass(const AName: string; const AFormClass: TFormClass);

procedure UnregisterFormClass(const AName: string);

function FindFormClass(const AName: string): TFormClass;

implementation

var  g_lstNames: TStringList; 

       g_lstForms: TClassList;

procedure RegisterFormClass(const AName: string; const AFormClass: TFormClass);

begin  

    g_lstNames.Add(AName);  

    g_lstForms.Add(AFormClass);

end;

procedure UnregisterFormClass(const AName: string);

var  

    Index: Integer;

begin  

    Index := g_lstNames.IndexOf(AName); 

    if Index <> -1 then 

    begin    

        g_lstNames.Delete(Index);   

        g_lstForms.Delete(Index);  

     end;

end;

function FindFormClass(const AName: string): TFormClass;

var  I: Integer;

begin  

for I := 0 to g_lstNames.Count - 1 do  

begin    

if g_lstNames[I] = AName then   

 begin     

 Result := TFormClass(g_lstForms.Items[I]);      

Exit;    

end;  

end;  

Result := nil;

end;

initialization  

g_lstNames := TStringList.Create;  

g_lstForms := TClassList.Create;

finalization  

FreeAndNil(g_lstForms); 

 FreeAndNil(g_lstNames);

end.  

以上是RegPak的主要代码,因为举例,代码很简陋。主要思想就是保存注册信息,提供查询方法。

让我们看看在DemoPak中的使用

unit AboutForm

;interface

uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  Dialogs, StdCtrls;

type  TfrmAbout = class(TForm)    

lblAbout: TLabel;  

private  

public  

end;

var  frmAbout: TfrmAbout;

implementation

uses FormReg;

{$R *.dfm}

initialization  

RegisterFormClass(TfrmAbout.ClassName, TfrmAbout);

finalization  

UnregisterFormClass(TfrmAbout.ClassName);  

end.  

在初始化时向RegPak的FormReg单元提交自己的类信息,因为每个Package在载入时无论动态静态都会自动初始化,而RegPak被主程序静态引用,肯定已经初始化,所以直接注册即可,非常简单。

最后看看主程序中的使用

uses  FormReg;

procedure TfrmMain.btnAboutClick(Sender: TObject);

var  hModule: THandle;

begin  

hModule := LoadPackage('DemoPak.bpl');  

try    

with FindFormClass('TfrmAbout').Create(nil) do    

try      

ShowModal;   

 finally     

 Free;   

 end; 

 finally    

UnloadPackage(hModule);  

end;

end;    

动态载入需要的包,查询需要的类的信息,使用之,最后卸载包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值