说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Delphi 插件创建、调试与使用应用程序扩展

HTML文档下载 WORD文档下载 PDF文档下载
Delphi 插件创建、调试与使用应用程序扩展

有没有使用过Adobe Photoshop如果用过,你就会对插件的概念比较熟悉。对外行人来说,插件仅仅是从外部提供给应用程序的代码块而已(举个例子来说,在一个DLL中)。一个插件和一个普通DLL之间的差异在于插件具有扩展父应用程序功能的能力。例如,Photoshop本身并不具备进行大量的图像处理功能。插件的加入使其获得了产生诸如模糊、斑点,以及其他所有风格的奇怪效果,而其中任何一项功能都不是父应用程序自身所具有的。

对于图像处理程序来说这很不错,可是为什么要花偌大的力气去完成支持插件的商业应用程序呢?假设,我们举个例子,你的应用程序要产生一些报表。你的客户肯定会一直要求更新或者增加新的报表。你可以使用一个诸如Report Smith的外部报表生成器,这是个不怎么样的解决方案,需要发布附加的文件,要对用户进行额外的培训,等等。你也可以使用QuickReport,不过这会使你身处版本控制的噩梦之中——如果每改变一次字体你就要Rebuild你的应用程序的话。

然而,只要你把报表做到插件中,你就可以使用它。需要一个新的报表吗?没问题,只要安装一个DLL,下次应用程序启动时就会看见它了。另外一个例子是处理来自外部设备(比如条形码扫描器)的数据的应用程序,为了给用户更多的选择,你不得不支持半打的各种设备。通过将每种设备接口处理例程写成插件,不用对父应用程序作任何变动就可以获得最大程度的可伸缩性。

入门

在开始写代码之前最重要的事情就是搞清楚你的应用程序到底需要扩展哪些功能。这是因为插件是通过一个特定的接口与父应用程序交互的,而这个接口将根据你的需要来定义。在本文中,我们将建立3个插件,以便展示插件与父应用程序相交互的几种方式。

我们将把插件制作成DLL。不过,在做这项工作之前,我们得先制作一个外壳程序来载入和测试它们。图1显示的是加载了第一个插件以后的测试程序。第一个插件没有完成什么大不了的功能,实际上,它所做的只是返回一个描述自己的字符串。不过,它证明了很重要的一点——不管有没有插件应用程序都可以正常运行。如果没有插件,它就不会出现在已安装的插件列表中,但是应用程序仍然可以正常的行使功能。

我们的插件外壳程序与普通应用程序之间的唯一不同就在于工程源文件中出现在uses子句中的Sharemem单元和加载插件文件的代码。任何在自身与子DLL之间传递字符串参数的应用程序都需要Sharemem单元,它是DelphiMM.dll(Delphi提供该文件)的接口。要测试这个外壳,需要将DelphiMM.dll文件从Delphi\Bin目录复制到path环境变量所包含的路径或者应用程序所在目录中。发布最终版本时也需要同时分发该文件。

插件通过LoadPlugins过程载入到这个测试外壳中,这个过程在主窗口的FormCreate事件中调用,见图2。该过程使用FindFirst和FindNext函数在应用程序所在目录中查找插件文件。找到一个文件以后,就使用图3所示的LoadPlugins过程将其载入。

{ 在应用程序目录下查找插件文件 }

procedure TfrmMain.LoadPlugins;

var

sr: TSearchRec;

path: string;

Found: Integer;

begin

path := ExtractFilePath(Application.Exename);

try

Found := FindFirst(path + cPLUGIN_MASK

0

sr);

while Found = 0 do begin

LoadPlugin(sr);

Found := FindNext(sr);

end;

finally

FindClose(sr);

end;

end;

{ 加载指定的插件 DLL. }

procedure TfrmMain.LoadPlugin(sr: TSearchRec);

var

Description: string;

LibHandle: Integer;

DescribeProc: TPluginDescribe;

begin

LibHandle := LoadLibrary(Pchar(sr.Name));

if LibHandle <> 0 then

begin

DescribeProc := GetProcAddress(LibHandle

cPLUGIN_DESCRIBE);

if Assigned(DescribeProc) then

begin

DescribeProc(Description);

memPlugins.Lines.Add(Description);

end

else

begin

MessageDlg(’File "’ + sr.Name + ’" is not a valid plug-in.’

mtInformation

[mbOK]

0);

end;

end

else

MessageDlg(’An error occurred loading the plug-in "’ +

sr.Name + ’".’

mtError

[mbOK]

0);

end;

LoadPlugin方法展示了插件机制的核心。首先,插件被写成DLL。其次,通过LoadLibrary API它被动态的加载。一旦DLL被加载,我们就需要一个访问它所包含的过程和函数的途径。API调用GetProcAddress提供这种机制,它返回一个指向所需例程的指针。在我们这个简单的演示中,插件仅仅包含一个名为DescribePlugin的过程,由常数cPLUGIN_DESCRIBE指定(过程名的大小写非常重要,传递到GetProcAddress的名称必须与包含在DLL中的例程名称完全一致)。如果在DLL中没有找到请求的例程,GetProcAddree将返回nil,这样就允许使用Assigned函数测定返回值。

为了以一种易用的方式存储指向一个函数的指针,有必要为用到的变量创建一个特定的类型。注意,GetProcAddress的返回值被存储在一个变量中,DescribeProc,属于TpluginDescribe类型。下面是它的声明:

type

TPluginDescribe = procedure(var Desc: string); stdcall;

由于过程存在于DLL内部,它通过标准调用转换编译所有导出例程,因此需要使用stdcall指示字。这个过程使用一个var参数,当过程返回的时候它包含插件的描述。

要调用刚刚获得的过程,只需要使用保存地址的变量作为过程名,后面跟上任何参数。就我们的例子而言,声明:

DescribeProc(Description)

将会调用在插件中获得的描述过程,并且用描述插件功能的字符串填充Description变量。

构造插件

我们已经创建好了父应用程序,现在该轮到创建我们希望加载的插件了。插件文件是一个标准的Delphi DLL,所以我们从Delphi IDE中创建一个新DLL工程,保存它。由于导出的插件函数将用到字符串参数,所以要在工程的uses子句中把Sharemen单元放在最前面。图4列出的就是我们这个简单插件的工程源文件。

uses

Sharemem

SysUtils

Classes

main in ’main.pas’;

{$E plg.}

exports

DescribePlugin;

begin

end.

虽然插件是一个DLL文件,但是没有必要一定要给它一个.DLL的扩展名。实际上,一个原因就足以让我们有理由改变扩展名:当父应用程序寻找要加载的文件时,新的扩展名可以作为特定的文件掩模。通过使用别的扩展名(我们的例子使用了*.plg),你可以在一定程度上确信应用程序只会载入相应的文件。编译指示字$X可以实现这个改变,也可以通过Project Options对话框的Application页来设置扩展名。

第一个例子插件的代码是很简单的。图5显示了包含在一个新单元中的代码。注意,DescribePlugin原型与外壳应用程序中的TpluginDescribe类型相一致,使用附加的export保留字指定该过程将被导出。被导出的过程名称也将会出现在主工程源代码的exports段中(在图4中列出)。

unit main;

interface

procedure DescribePlugin(var Desc: string);

export; stdcall;

implementation

procedure DescribePlugin(var Desc: string);

begin

Desc := ’Test plugin v1.00’;

end;

end.

在测试这个插件之前,要先把它复制到主应用程序的路径下。最简单的办法就是在主目录的子目录下创建插件,然后把输出路径设置为主路径(Project Options对话框的Directories/Conditionals也可以作这个设置)。

调试

现在介绍一下Delphi 3中一个较好的功能:从IDE中调试DLL的能力。在DLL工程中可以通过Run paramaters对话框指定某程序为宿主应用程序,这就是指向将调用DLL的应用程序的路径(在我们这个例子中,就是刚刚创建的测试外壳程序)。然后你就可以在DLL代码中设置断点并且按F9运行它——就像在一个普通应用程序中做的那样。Delphi会运行指定的宿主程序,并且,通过编译带有调试信息的DLL,把你指引到DLL代码内的断点处。

在Access 2000中用ADO-VB资料 在Access数据库中实现密码管理的另一种方式 -VB资料 在VB6.0中使ACCESS数据库在网络使用中保持同步 在VB中更改SQL Server数据库结构 在VB中兼容非ACCESS数据库的技巧 在VB中引用dbf及索引文件 在VB中运行Microsoft Access报表的好方法 在VB中直接用ODBC API访问数据库 在数据库应用中, 经常要动态生成 Select 语句,典型的情况:-VB资料 在运行时修改DataEnvironment的连接字符串-VB资料 在抓取資料庫之資料前先計算資料總筆數 -VB资料 增加 MsFlexGrid 的编辑功能-VB资料 真正删除数据库的记录 -VB资料 用VB制作屏幕保护程序 VB多媒体程序设计 VB设计动画时钟 VB游戏写作技巧(1)秀图篇 VB游戏写作技巧(2)网络篇 VB中播放WAV文件 VB中播放三维动画编程一例 Visual Basic 5.0多媒体创作技巧 Visual Basic 5.0中实现视频画中画 Visual Basic 中制作流水灯 Visual Basic动画编程技术 Visual Basic环境下Video/ Audio压缩数据流播放技术 Visual Basic设计多媒体应用程序 Visual Basic影音控制 Web动画图像分解在VB动画设计中的应用 播放 .flc 动画 -VB资料 播放 AVI -VB资料 播放MP3文件 -VB资料 请问广州市的朋友,哪儿有旺盛的二手电脑市场? 怎样在VB里用代码设置ACCESS数据库密码 为什么【select * from Topics [OrderBy 发表时间 desc]】和【...[OrderBy 发表时间 desc]】效果一样? 用SUN WTK2.0开发的程序在Nokia模拟器下可编译不可运行,请教 第一个不头晕者接分 杭州工作难找!!!! 如何修改tomcat 4.1.18的配置,使修改过的Servlet能够及时重新加载! edit的text读取 关于ocx的问题? 怎样将一个文本文件以二进制的形式显示 请大家帮我一下!! 怎么破解Email密码? 国内手机及PDA大都用的是哪个操作系统?Palm? 如何是MEMO中增加一行后光标保持在最后位置? vb.net怎样选定word中表格的某一行? ado+intraweb中如何调用coInitialize? 寻找最恶心的笑话 一些对未来的思索、问题,各位来谈谈 有谁知道用哪款打印机比较好呢? 关于类和接口设计问题 如何能把98 聯入2000 如何做一个后台管理-数据库备份程序 如果我用一个Winsock(index)控件数组。Winsock(1)、Winsock(2)同时调用一个延时函数会出什么问题吗? 已知表中字段ID的值,如何定位到这个字段? 谁知道为什么会出这种错误fatal error C1004: unexpected end of file found 小小问题,也有小小的分,不成敬意。 visio ,rose ,ERwin 他们各自的用途是什么,有什么区别呀? Oracle安装的问题——寻求帮忙!!!! 请问Crystal(水晶)报表如何对TextBox进行动态绑定字段? 如何设定mapx图层的颜色 对汇编的渴望! 谁有Asp做的网站?100分奉上! 都进来看看 vc新兵问函数调用菜鸟问题 紧急求救!!!! 谁有delphi关于ado编程 的资料啊(要详细一点的) TreeView的问题,很实在的问题。 关于在PB上实现错误事件处理!!! 关于组件的停靠 用VB.NET连接数据库老是连不了,快精神分裂了,救命啊! 关于SendMessage(高分相送,紧急) 急!!!高手进! 在查找结果中如果某一字段的值相等,只取出其中一条的问题! squid的安装问题???????????????????? SQL语句问题? 冒昧求救,光驱不能使用,不能boot 我的主机总收到外面发的广告信息? 高分求助急!!! 见鬼了,我添加一个TServerSocket控件,然后编译出现:Declaration terminate incorrectly 有谁知道用哪款打印机比较好呢? 按钮BitBtn1上有图片,在图片上写字的问题。(在先给分!) 在下列化学变化过程中:X+HCL →Y+ NaOH→Z →X所代表的物质可能是A.CuOB.KOHC.K2OD.SO2 COS 165º=?求过程,结果也行 何以解忧 唯有杜康 作文 HCL与NAOH反应是化学变化,其中的物理变化在哪?书上不是说化学变化一定伴随着物理变化吗? cos-165°怎么求?注意是负的 “何以解忧,唯有杜康”的作者是: 燎麻照读中的“自以少时未开悟,晚更历精,明慧过人.”怎么翻译 为什么cos(-α-π)=-cosα?求具体的解题过程 四选一:长期大量饮酒对人体的哪个脏器损害最严重?A、心脏B、肝脏C、肾脏D、脑 怎样才能保证水源、土壤不会受到粪肥外流液体的污染,做到有机性 热水为什么会让东西变软?马上要用! 长期大量饮酒对身体哪些脏器有损害?容易得什么病? 什么溶液与硫酸铜溶液反应生成二氧化硫 为什么植物遇热会变软?是这样的,我看老妈做饭的时候韭菜在锅里翻炒了一会,就软塌塌的了,求各位大神告知小妹这到底是怎么一回事? 铝合金的Hemlok结构型抽芯铆钉有什么特点? 铷与硫酸铜溶液反应生成so2气体吗 读了文言文《孔子家语》 用一句话概括你的感想《孔子家语·六本》君子慎其处 孔子曰:“吾死之后,则商也日益,赐也日损.”曾子曰:“何谓也?”子曰:“商也好与贤已者处,赐也好说 一瓶煤气多少钱?带瓶子一起买的 已知反应Cu+2H2SO4===SO2↑+CuSO4+2H2O,当在标准情况下已知反应Cu+2H2SO4(浓)===SO2↑+CuSO4+2H2O,当在标准情况下,得到448ml的气体时,求(1)消耗的铜的质量(2)转移电子数 弱电解质为什么在离子反应中不可拆,它不是也有部分电离吗难道它所电离出的那少部分离子就忽略不计了? 甲基丙烷只有一种情况吧?有 2-甲基丙烷 那个2不写行吗? 硫酸钾溶液酸碱度? 细胞的失水与吸水可以用扩散作用解释吗? 2-甲基丙烷中的“2-”是什么意思? 等物质的量浓度等体积的碳酸钾、硫酸钾、氯化氢混合后、PH为什么小于7 怎样确定风向 2 甲基丙烷的二溴代物有几种?三个甲基是不是都一样 鉴别1甲基2溴乙烷,1,1二甲基2溴乙烷,1溴丙烷 用化学方法鉴别,详细点 某地风向如何确定 参与身体全部物质交换的是()参与身体全部物质交换的是() A.体循环B.血液循环另一种为什么不是? 请问氯化亚铁和硫酸铜为什么不发生氧化还原反应?如题…… 文言文 吊者言孙叔敖为楚令伊,一国史民皆来贺.有一老父,衣粗衣,冠白冠,后来吊.孙叔敖正衣冠而出见之,谓老父曰:“楚王不知臣不肖,使臣受史民之垢,人皆来贺,子独来吊,岂有说乎?”父曰: 女孩喝酒对身体有什么严重的伤害 燎麻照读阅读答案1、解释下列字(“”)“及”觉复读( ) “咸”见申擢( ) “俱”奔江南( ) 必往“祈”借( )2、用自己的话说说刘俊是怎样刻苦读书的.3、“悬梁刺股”“焚 爸爸问他在干什么文言文怎么说主要是在干什么怎么说 2,2-二甲基丙烷和2-甲基丙烷熔沸点问题!当C数相同时,比较支链(或对称性),越多,熔沸点越小.答案1大于2,但我觉得1的支链更多啊,( CH3-C(CH3)2-CH3)也更对称,为什么答案是2更小? 阳光的强弱与物体吸收热有怎样的关系? 溶质与溶剂分别是什么 赤橙黄绿青蓝紫怎么样 阳光的强弱与物体吸收热有什么关系? t℃时,向100g质量分数为20%的氢氧化钠溶液中加入等质量的硫酸溶液,恰好完全反应,并测得反应后溶液的P等于7,然后蒸发掉39.5g水,再冷却到t℃,恰好成为饱和溶液,求:t℃时生成物的溶解度 家庭用电和煤气那样划算?现在煤气家庭用大瓶的要一百多一瓶,电也要1块钱一度,平时就是洗澡烧水和煮吃的,用煤气划算还是用电划算?我说的是普遍情况下,你是怎么计算的? 物体在吸收阳光的同时是否也吸收热?证据是什么? 用丙烯颜料怎么画出海边岩石的颜色最近在做场景 想在石膏做的岩石上面画出海边岩石上的颜色 来体现出海边的场景.要怎么才能画出海边岩石的颜色 用电还是用煤气实惠?我租房那里,电费1.5元一度,煤气大罐的130元一罐,请问,煮菜做饭烧水用电实惠还是用煤气实惠? 如果物体热胀冷缩,为什么太阳那么热,却不会变大,充斥整个天空呢?为什么冷寂的悲伤,却占据了世界呢. 动物的古文有多少要多少, 文言文工作中的工是什么意思? 解释为主持,管理的文言实词 文言文古文 吴老师用72厘米的铁丝做开一个长方形的教具,长20厘米,宽多少厘米 文言文矛与盾这个文言文的起因是什么?发展是什么?结果是什么? 铆钉孔一般多大?单位mm~ 最新中国十大油漆排名榜 化肥污染知多少? 有什么书值得看的,关于管理,哲理,或古文,还有观念的 铆钉的选择 大小长度 根据什么来的?应如何选择?比如什么时候选择M4 M6的?还有他的长度? 化肥会不会农田污染? 若cos(a-15°)=-1/3则cos(165°+a)=? 镁铝铁混合粉末24克,与足量的盐酸反应,得到的气体体积不可能为A.9.6升B.11.2 升C.22.4升D.29 升 德国社民党称需要成立调查委员会 斯诺英国发生强烈暴风雨天气已致4死 逾6遵义市委书记廖少华被调查 曾多次强调英国发生强烈暴风雨天气已致4死 逾6德国社民党称需要成立调查委员会 斯诺安倍突访土耳其 传为劝阻土放弃购中国媒体称废品价格10年不涨 收一车东西江苏沛县办公楼豪华超标 称四套班子领坦桑尼亚军方证实一名坦维和军人在刚果温岭数百医护人员哀悼遇害医生 上百医纽约油价28日继续反弹纽约华裔灭门案凶手因妒忌动杀机 与被安理会将与伊斯兰合作组织加强合作俄罗斯外长说俄乌贸易关系不会破裂40余名非洲移民渴死于尼日尔沙漠中央巡视组“寻虎找蝇”聚焦以权谋私等黎巴嫩真主党呼吁通过政治途径解决叙利伦敦股市股指28日上涨德国法兰克福股市DAX指数28日下跌河北宣化女村官称遭官员性骚扰 出示微丝绸之路国际大会在伊斯坦布尔举行泰小狗撩水救鱼 感动数百万网友瞄准AA(含)以下信用债博时优势收益爬山虎“染绿”二环高架3000根桥墩涉嫌买卖国家机关证件罪车市,迎来变革张艺谋不愿和解 坚持和张伟平打官司广东市场价格战已持续一年多苏宁奥莱城百日庆三日狂购家人各种病缠身爱情片混战 8 月档 喜剧大片任你选汤唯嫁韩国 欧巴都想跟她合作精明主妇华西社区看车团今日启动上八小时购物网买野生鲜松茸沉睡的8万份档案周末焦点赛事预测陶企,竞合加速捡废品难撑学业实体为本 资本为辅开展批评和自我批评 内江市市中区朝阳四川特色水果受青睐 首轮投票今天结束
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘