无痛使用Delphi Package( 二 )


动态载入代码基本上是无痛使用 , 只要路径配置没有问题 , 基本上和使用普通单元没有区别
implementationusesUnit2, Unit3;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);beginshowmessage(TUser.create().showString());varFrom3 := TForm3.create(nil);From3.visible := true;end;动态加载动态加载和静态加载相反 , 无论是载入还是释放都要自己来处理 , 看起来好像是动态载入,这种方式个人感觉相当麻烦 , 虽然本质上和dll的动态加载一样 , 但是因为在导入的元素中多了类的概念 , 所以还需要使用反射的方式创建类的对象才能实现类成员的引用
implementationuses rtti, System.StrUtils;{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject);var// 声明和Package导出列表中一致结构的过程add01: procedure(Msg: String); stdcall;// 声明和Package导出列表中一致结构的函数add02: function(Num1: Integer; Num2: Integer): Integer; stdcall;begin// 载入bpl格式的PackagevarPackageHandle := LoadPackage('Package1.bpl');if PackageHandle <> 0 thenbegin// 载入成功之后获取对应函数、过程的指针@add01 := GetProcAddress(PackageHandle, 'ShowMsg');@add02 := GetProcAddress(PackageHandle, 'add');if @add01 <> nil thenbegin// 调用add01('HelloWorld');showmessage(add02(1, 2).Tostring);end;end;// 对于类我们需要先创建类的对象然后才可以实现类中函数的调用var// 创建运行期上下问对象rc := TRttiContext.create;var// 载入对应单元中的类 , 注意此处需要写单元名+类名ClassType := rc.FindType('Unit2.TUser');var// 获取元类实例(对象)Instance := ClassType.AsInstance;var// 获取该实例的元信息类型QRClass := Instance.MetaclassType;var// 获取用于创建TUser类型的构造方法CreateMethod := Instance.GetMethod('Create');var// 利用获取到的构造方法对象 , 创建TUser类对象User := CreateMethod.Invoke(QRClass, []);var// 函数调用rs := ClassType.GetMethod('ShowString').Invoke(User, []);// 显示返回值showmessage(rs.asstring);//卸载包UnloadPackage(PackageHandle);end;从上面动态加载的代码可以看出涉及到反射相关的知识 , 个人感觉这种方式在使用起来不太方便 , 当然如果对反射比较熟悉的话那就没问题了
动态载入参考代码我在搜索Package相关内容的使用看到下面这段代码 , 它也可以实现创建类的对象 , 只是中间出现的类型的强制转换 , 个人不是特别推荐 , 只是记录一下作为笔记参考
function CreateFormByClassName(ClassName: string): integer;varAClass: TPersistentClass;AForm: TCustomForm;beginResult := mrNone;AClass := GetClass(ClassName);if AClass <> nil thenbeginAForm := TComponentClass(AClass).Create(Application) as TCustomForm;Result := AForm.ShowModal;end;官方参考文档官方文档是英文的 , 我也是翻看+翻译读了很久挑了几篇有用的

  • (Delphi)