delphi的BPL应用

2023-11-09 02:10
文章标签 应用 delphi bpl

本文主要是介绍delphi的BPL应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近一直在测试BPL和DLL,总结一下这段时间的经验。
如果是模块化架构,就选择BPL,不要选择DLL,DLL可以对外做接口使用,不过Delphi接口我觉得DataSnap更方便点。为什么要用BPL呢,因为DLL是无法传递对象的,只能传递对象的内存地址过去。BPL就可以实现对象的传递。
使用BPL的注意事项,首先一定要注意Debug 和Release 两种编译是有很大区别的。直接Release编译最好,主程序也要用Release编译调用,如果编译类型不同,会有异常提示。BPL里面各个Form和Unit之间的调用,需要注意的如果用到了Form的控件,记得一定要把Form对象传过去。这样获取才不会出问题。BPL调用BPL的时候,也要把Form传过去,传回来的时候再转换回来。下面说下调用案例。
我是一个主程序,两个BPL
主程序调用的代码

procedure TFMenuItem.Label1DblClick(Sender: TObject);
varBPLHandle: HMODULE;frm: TCustomForm;AClass : TPersistentClass;SetUser:procedure(sform:TForm;User:String;IP:String;Port:Integer);newPage:TAdvTabSheet;Path:String;ClassName:String;SetName:String;
begin//BPL的目录和名称Path:='System/'+Copy(self.Caption,1,2)+'.bpl';//调用的Form的名称ClassName:='T'+self.Caption;//BPL里面的过程名称SetName:=self.Caption+'SetUser';//加载BPLBPLHandle := LoadPackage(Path);//加载后获取过程@SetUser := GetProcAddress(BPLHandle, Pchar(SetName));if BPLHandle > 0 thenbegin//获取FormAClass := FindClass(ClassName);if AClass<>nil thenbegin//新增一个Page页面newPage:=TAdvTabSheet.Create(FMyMain.AdvPageControl2);newPage.Caption:=Label1.Caption;newPage.Color:=clWhite;newPage.AdvPageControl:=FMyMain.AdvPageControl2;newPage.ShowClose:=True;FMyMain.AdvPageControl2.ActivePage:=newPage;//创建BPL的Form实例frm:=TComponentClass(AClass).Create(Application) as TCustomForm;if @SetUser<>nil then//执行BPL里面的过程SetUser(TForm(frm),'admin',FMyMain.DSRestConnection1.Host,FMyMain.DSRestConnection1.Port);//放入新建的Page里面frm.Parent:=newPage;//显示frm.Show;// frm.Free;endend
end;

第一个BPL的代码

unit User;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, DBGridEhGrouping, ToolCtrlsEh,DBGridEhToolCtrls, DynVarsEh, FireDAC.Stan.Intf, FireDAC.Stan.Option,FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf,FireDAC.DApt.Intf, Vcl.ComCtrls, Vcl.ToolWin, System.ImageList, Vcl.ImgList,Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, EhLibVCL, GridsEh,DBAxisGridsEh, DBGridEh, AdvEdit, AdvEdBtn, Vcl.StdCtrls, Vcl.ExtCtrls,Datasnap.DSClientRest, FireDAC.Stan.StorageJSON,FireDAC.Stan.StorageXML, FireDAC.Stan.StorageBin,DataBase;type//定义回调过程MeADD=procedure(DepCode:String;DepName:String;MyForm:TForm);TF901 = class(TForm)Panel1: TPanel;Label1: TLabel;Label2: TLabel;Label3: TLabel;Label4: TLabel;Label5: TLabel;Label6: TLabel;Edit1: TEdit;Edit2: TEdit;Edit3: TEdit;Edit4: TEdit;Edit5: TEdit;Edit7: TEdit;Edit6: TAdvEditBtn;Panel2: TPanel;DBGridEh1: TDBGridEh;Panel3: TPanel;DataSource1: TDataSource;FDMemTable1: TFDMemTable;ImageList1: TImageList;ToolBar1: TToolBar;ToolButton1: TToolButton;ToolButton2: TToolButton;ToolButton3: TToolButton;ToolButton4: TToolButton;ToolButton10: TToolButton;ToolButton5: TToolButton;ToolButton6: TToolButton;ToolButton7: TToolButton;ToolButton8: TToolButton;procedure ToolButton1Click(Sender: TObject);procedure ToolButton2Click(Sender: TObject);procedure ToolButton3Click(Sender: TObject);procedure ToolButton4Click(Sender: TObject);procedure ToolButton10Click(Sender: TObject);procedure FormShow(Sender: TObject);procedure ToolButton8Click(Sender: TObject);procedure Edit6ClickBtn(Sender: TObject);private{ Private declarations }public{ Public declarations }varUserNo:String;MyDataBase:TDDataBase;end;//定义给主程序调用的过程procedure F901SetUser(sform:TForm;UserNo:String;IP:String;Port:Integer);//定义一个跟回调过程一样的过程,这个用于回调过程功能实现procedure SetDep(depcode:String;depname:String;MyForm:TForm);
varF901: TF901;implementation
Uses DataPost;
{$R *.dfm}//给主程序调用的过程
procedure F901SetUser(sform:TForm;UserNo:String;IP:String;Port:Integer);
beginTF901(sform).UserNo:=UserNo;TF901(sform).MyDataBase:=DataPost.ConnectData(IP,Port);
end;//一个跟回调过程一样的过程,这个用于回调过程功能实现
procedure SetDep(depcode:String;depname:String;MyForm:TForm);
beginTF901(MyForm).Edit7.Text:=depcode;TF901(MyForm).Edit6.Text:=depname;
end;//BPL里面调用另外一个BPL
procedure TF901.Edit6ClickBtn(Sender: TObject);
varBPLHandle: HMODULE;frm: TCustomForm;AClass : TPersistentClass;DepSetUser:procedure(sform:TForm;tForm:TForm;User:String;IP:String;Port:Integer);PMeADD:procedure(me:MeADD);
begin//加载BPLBPLHandle := LoadPackage('Share/DepBPL.bpl');//这里跟主程序调用的一样,调用另外一个BPL的过程@DepSetUser := GetProcAddress(BPLHandle, 'DepSetUser');//另外一个BPL回调本BPL的过程@PMeADD := GetProcAddress(BPLHandle, 'PMeADD');if BPLHandle > 0 thenbegin//获取FormAClass := FindClass('TFQueryDep');if AClass<>nil thenbegin//创建另外一个BPL的Form实例frm:=TComponentClass(AClass).Create(Application) as TCustomForm;if @DepSetUser<>nil then//调用里面的过程 DepSetUser(TForm(frm),self,'admin',MyDataBase.DSRestConnection1.Host,MyDataBase.DSRestConnection1.Port);if @PMeADD<>nil then//把实现回调功能的过程传过去PMeADD(SetDep);frm.ShowModal;frm.Free;endendend;procedure TF901.FormShow(Sender: TObject);
beginDataPost.ButtonPower(Self.Name,self.UserNo,self.ToolBar1,self.MyDataBase);DataPost.F901OpenData(self);
end;procedure TF901.ToolButton10Click(Sender: TObject);
beginDataPost.F901Cancel(self);
end;procedure TF901.ToolButton1Click(Sender: TObject);
beginDataPost.F901Add(self);
end;procedure TF901.ToolButton2Click(Sender: TObject);
beginDataPost.F901Update(self);
end;procedure TF901.ToolButton3Click(Sender: TObject);
beginDataPost.F901Delete(self);end;procedure TF901.ToolButton4Click(Sender: TObject);
beginDataPost.F901Save(self);
end;procedure TF901.ToolButton8Click(Sender: TObject);
beginDataPost.F901Cancel(self);
end;//这里是给主程序显示可调用的过程
exportsF901SetUser;//这里把Form给主程序定位Form使用
initializationRegisterClass(TF901);
finalizationUnRegisterClass(TF901);end.

第二个BPL代码

unit QueryDep;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, DBGridEhGrouping, ToolCtrlsEh,DBGridEhToolCtrls, DynVarsEh, EhLibVCL, GridsEh, DBAxisGridsEh, DBGridEh,FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,FireDAC.Stan.Async, FireDAC.DApt, Data.DB, FireDAC.Comp.DataSet,FireDAC.Comp.Client, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Imaging.pngimage,Vcl.ShadowForms,Datasnap.DSClientRest,system.IniFiles,Data.FireDACJSONReflect,FireDAC.Stan.StorageXML, FireDAC.Stan.StorageJSON, FireDAC.Stan.StorageBin;type//定义回调过程MeADD=procedure(DepCode:String;DepName:String;MyForm:TForm);TFQueryDep = class(TShadowForm)DBGridEh1: TDBGridEh;DataSource1: TDataSource;Panel1: TPanel;Label4: TLabel;Image1: TImage;Panel3: TPanel;Panel4: TPanel;DSRestConnection1: TDSRestConnection;FDMemTable1: TFDMemTable;FDStanStorageBinLink1: TFDStanStorageBinLink;FDStanStorageJSONLink1: TFDStanStorageJSONLink;FDStanStorageXMLLink1: TFDStanStorageXMLLink;procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure FormDestroy(Sender: TObject);procedure DBGridEh1DblClick(Sender: TObject);procedure Image1Click(Sender: TObject);procedure FormShow(Sender: TObject);private{ Private declarations }public{ Public declarations }varUserNo:String;//用于接收上一个BPL的Form,后面调用回调过程的时候会传回去Form:TForm;end;//顶一个回调过程功能实现,用于调用上一个BPL的回调过程接收procedure PMeADD(me:MeADD);//定义上一个BPL调用过程procedure DepSetUser(sform:TForm;UserNo:String;IP:String;Port:Integer);varFQueryDep: TFQueryDep;FMeADD:MeADD;implementation
Uses Server;{$R *.dfm}
//上一个BPL调用过程的功能实现
procedure DepSetUser(sform:TForm;UserNo:String;IP:String;Port:Integer);
beginTFQueryDep(sform).UserNo:=UserNo;TFQueryDep(sform).Form:=sform;TFQueryDep(sform).DSRestConnection1.Host:=IP;TFQueryDep(sform).DSRestConnection1.Port:=Port;
end;
//用于接收传过来的过程
procedure PMeADD(me:MeADD);
beginFMeADD:=ME;
end;procedure TFQueryDep.DBGridEh1DblClick(Sender: TObject);
begin
//调用回调过程,把值和Form传回去   FMeADD(DBGridEh1.DataSource.DataSet.FieldByName('cDepCode').AsString,DBGridEh1.DataSource.DataSet.FieldByName('cDepName').AsString,Form);close;
end;procedure TFQueryDep.FormClose(Sender: TObject; var Action: TCloseAction);
begin//  Action := caFree;
end;procedure TFQueryDep.FormDestroy(Sender: TObject);
beginFQueryDep := nil;
end;procedure TFQueryDep.FormShow(Sender: TObject);
varServer: TServerMethods1Client;DSlIST: TFDJSONDataSets;
beginServer := TServerMethods1Client.Create(DSRestConnection1);DSlIST := Server.ServerGetTable('select * from Department order by cDepCode', UserNo, 1);FDMemTable1.FieldDefs.Clear;FDMemTable1.Close;FDMemTable1.Data := TFDJSONDataSetsReader.GetListValue(DSlIST, 0).Data;FDMemTable1.Open;
end;procedure TFQueryDep.Image1Click(Sender: TObject);
beginclose;
end;//给另外一个BPL获取过程使用
exportsPMeADD,DepSetUser;//给另外一个BPL获取Form使用
initializationRegisterClass(TFQueryDep);
finalizationUnRegisterClass(TFQueryDep);end.

主要代码就这些
调用第一个BPL
在这里插入图片描述
通过第一个BPL调用第二个BPL

在这里插入图片描述

点击后,把第二个BPL的值,通过回调过程传递到一个BPL里面
在这里插入图片描述

这篇关于delphi的BPL应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/373575

相关文章

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

java中VO PO DTO POJO BO DO对象的应用场景及使用方式

《java中VOPODTOPOJOBODO对象的应用场景及使用方式》文章介绍了Java开发中常用的几种对象类型及其应用场景,包括VO、PO、DTO、POJO、BO和DO等,并通过示例说明了它... 目录Java中VO PO DTO POJO BO DO对象的应用VO (View Object) - 视图对象

Go信号处理如何优雅地关闭你的应用

《Go信号处理如何优雅地关闭你的应用》Go中的优雅关闭机制使得在应用程序接收到终止信号时,能够进行平滑的资源清理,通过使用context来管理goroutine的生命周期,结合signal... 目录1. 什么是信号处理?2. 如何优雅地关闭 Go 应用?3. 代码实现3.1 基本的信号捕获和优雅关闭3.2

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个