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

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代码内的断点处。

VB如何在表中保存单引号? VB如何抓出 Access 的 Table 欄位中的【敘述】部份呢? 实现Access数据库的Web查询-VB资料 使用Visual Basic访问数据库几个注意的问题 数据库查询-VB资料 数据约束控件和 RecordSet-VB资料 锁住数据库中的表 -VB资料 谈谈VB的数据库编程方式 为VB5辩解: VB处理数据库时求数据表记录总数的最佳方法 为什么安装后的数据库应用总是路径不对或找不到? 返回 -VB资料 无论如何,就是只能输入数字-VB资料 VB用 DAO 或 ADO 正确访问 Access 2000 VB用CELL组件显示Access数据库的图片对象 VB用DAO打开Excel文件 VB用DATA控件绑定报表控件打印报表 VB用EXCEL来打印报表并生成折线图 VB用EXCEL组件简化VB编程的一种方法 VB用MDB文件做密码库 VB用ODBC API访问ODBC数据库 用VB 实现类电子表格的数据录入 用VB5直接控制Excel 97 用VBA编制Access的查询程序 用VB和RDO访问SQL Server 用VB开发多通道仪表数据采集程序 用VB实现关闭所有数据库对象 用VB实现类电子表格的数据录入 VB用代码创建数据库,表,字段 VB用类来编写数据库程序 优化OLE的调用频率-VB资料 语言选择引起的查询错误 -VB资料 远程数据库的访问-VB资料 各位大虾请进 求:0,1,-1的N长度组合算法 各位问一个比较少见的问题100分相送,急急急!!! 这样的条件判断语句要怎么写?(很简单的) 一款很不错的电子图书制作、资料管理软件 在-卢-<<利用XML实现通用WEB报表打印>>时报:未将对象引用设置到对象实例 DBEdit如何限制输入格式? 简单问题 ★★★狂急!请问怎样取得文件的创建日期!在线等!在线结贴!★★★ 初学xml,很简单的问题,就是不会,各位近来看看!一行代码搞不定… 有没有用于unix下c开发的dbx调试图形界面的工具? 哪位有tar 和 gzip 命令参数的详细中文介绍 jsp网站测试,欢迎大家测试 提问 请问有没有直接可以HTML(XHTML、SHTML)生成XML-XSL!!的工具 进程外组件的关于注册的问题? jsp中怎样生成静态页面 请问:如何返回webservice类的一个或多个实例? 怎样触发另一个窗口中的javascript函数? 谁能提供一些检测内存泄露的工具或方法 如何将 FoxBase 中的数据导入到 SQL Server 中? 求助:API操作注册表出现奇怪问题 请问如何改变windows xp中的用户的登陆顺序 有问题:如何通过页面下载附件? 求助:VB生成安装文件的问题 下面的程序怎样优化?(着急) 怎么样在C++ Builder 的Form上显示文字!我不要用控件,要直接显示在Form上 200 分相送 高手请进 请教如何写成特殊格式文件的存取的问题. 适配器更新数据集怎么用事务 怎样才能设“开机密码”? 哪位高手可以给我介绍一下TOMCAT和APACHE,我刚接触,需要了解一下 关于SocketConnection. 进入linux8.0后,主板指示灯闪烁问题,请高手指教。 谁给一个QQ给我啊? 高分请教? 如何查看一个记录集中游标的位置。 求一个简单的窗口函数 请问如何实现计算器功能 如何修改这个脚本?(应该比较简单) 大伙能否谈谈.net整体软件框架的设计 来者有分:调查:大家是在用vc.net还是用vc60,我在用vc60 用SQL SERVER如何实现插入数据后立刻取出插入的数据的id?在线等待,急~~~~~~~ 关于JTree ppt 大家帮我看看这个方法错在哪里?分不是问题 请问获取中文操作系统下获取文件信息时lang-charset的取值为什么????? CSDN论坛左边的树形栏目能动态添加吗? 如何设置几秒钟后转向某页面那种效果。 用户需求分析说明书和系统分析说明书到底是不是一回事!! 发邮件时,收到的邮件竟然是乱码,如何解决?100分大放送 affirm和allege的区别用法和意义上 武则天和唐玄宗之间是什么关系 HCl+NaOH=NaCl+H2O 上式中的盐酸是稀是浓? 哪位ANSYS高手解决一下 constraint equation 1 has no unique degree of freedom 哪里出错误了?constraint equation 4 has no unique degree of freedomANSYS模态分析 最后计算出现这个问题 搜索网上出错的地方,有一个212什 在一个圆中有两条弦相交于一个定点且这两条弦互相垂直.求这两条弦乘积的最大值和最小值. 为什么小颗粒会向水漩涡中心去 拨云见日的意思 土壤水解性氮的测定中使用什么规格的微量滴定管?有液相色谱仪,但不知到检测方法,望好事做到底,提供详细检测方案。可发到wangchuan.888@136.com邮箱,先谢谢了。 医院里面的X光是干什么用的. 2005年5月11日,台湾亲民党主席宋楚瑜应邀到清华大学演讲.此前北京连日下雨,这一天阳光灿烂.演讲一开始,宋楚瑜就以“拨云见日”来表达他此时的感慨.请问“拨云见日”的双重含义是?请帮 requested feature is not available X射线的应用 拨云见日什么意思 sketchup如何用测量工具实现缩放rt 我要把一个物体缩放到一个实际尺寸 用测量工具以前可以 输入一个数字整体就变了 现在忘记怎么弄的了 - 已知集合A=﹛1,2,3,K),B=﹛4,7,a,a+3a),且A∈Z,K∈Z,映射f:x箭头y=3x+1,x∈A,y∈B,求实数a、k的值. 拨云见日的含义 sketchup模型大比例缩放后,点击进入块时会出现观察上的破面,使继续修改时很难进行,如何避免?是指观察时产生破面 实际上并没有破,如何做到缩放后还能继续操作修改?我指的是大比例缩放后 如何画一个标准椭圆 拨云见日的感觉是什么意思 邓小平在文化大革命时期,情况如何?后期有没有掌权,做出贡献 There is ( )“s” in the word “six”. 垂体和甲状腺为什么可以相互调节?甲状腺的负反馈不是作用于下丘脑吗? 电子显微镜中,能不能用X-ray取代电子光源,为什么 怎么样画一个标准的椭圆, 翻译two-linear-degree-of-freedom robot 电镜技术中可否用X-ray取代电子光源 There is _____ “s” in the word “six” 怎么答 自来水管呜呜叫怎么回事 成为拨乱反正和改革开放的思想先导的事件是什么 ICPMAX和X光衍射仪和扫描电镜和气象色谱仪和原子吸收的实验室安装条件,知道一个也行啊, 自来水管为什么会响?我家的自来水管经常响,而且声音非常大,有时象火车的轰隆声,有时象火车的汽笛声,吵得人睡不着觉.为什么会这样? 过圆内某点的弦中,垂直于直径的弦最短.是不是定理? 马克思主义哲学原理(第2版)课后题答案陈先达主编,人民大学出版社的版本.就要课后复习题的答案.有的请速发,分稍后给主要是内容提要里面的文字表述不严谨,要是考试答题那么些的话能得 什么叫极限跑酷运动? 反身代词的用法?youself herself himself itself myself themselves ourselves yourselves 的用法主要想知道他们分别在什么情况下用 请问长期在X光操作间会不会有什么影响? testify和verify的区别,用中文举例说说?可以参考这题:The plane found the spot and hovered close enough to ___ that it was a car.A.verify B.testify 告诉我 英语反身代词 的用法 谢谢啦 用x光给土拍摄照片如果我我用x光给泥土拍摄,会得到什么?黑糊糊的一片?土中的部分杂质?能穿透有机玻璃吗? confirm,ascertain,substantiate 区别?confirm,ascertain,substantiate 都有“确认、证实”的意思,怎么区分? 第四题. 计算下列极限.题目如图.答案是二分之一.但过程我不懂. 漩涡为什么能向中心吸物体 confirm和verify哪个可以搭配figuresQ:Did you (verify) (confirm) these figures?用confirm好,还是verify好?为什麽?请详细说明理由,不要只是复制粘贴,谢谢~!有独到见解的给与加分~!请高手解答~不胜感激…… ANSYS中 size cntrls是什么意思 漩涡为什么中间低两边高 凸透镜的成像规律物距和像距的关系当 f 求懂的人忙我做两道CAD的题.要写作图步骤如题 看好是做题步骤啊,这个东西对我很重要 祝你们永远快乐!谢谢各位哥哥姐姐们了我只有5分了 不能多给你们了 请哥哥姐姐们多费心了 已知,集合A={x|-2≤x≤2},B={x|-x ≤x≤1}对应关系f:x→y=ax若在f的作用下能够建立从 A到B的映射f:A→求实数a的取值范围.主要是B={x|-x ≤x≤1}弄不清 CF常说别BB N0 cassete with paper of the size requested is available是什么意思 已知集合A={xl-2≤x≤2},B={xl-1≤x≤1},对应关系f:x到y=ax,若在f的作用下能够建立从A到B的映射,求实数a的取值范 为什么水壶烧开好壶嘴烧开后一定距离才能看见白气 求反身代词的各种用法~(高三英语) 草菅人命 造句 基本放大电路动态分析中把直流电压源视为“接地”,为什么是视为“接地”?而不是视为其他.我是知道“叠加原理”的,我的意思是为什么不把它开路悬空分析,而是要接地 打印时出现英文对话框是什么意思?英文是No cassette with paper of the size requested is available当在电脑上点打印时,出现一个对话框对话框是英文No cassette with paper of the size requested is available 然后就打 草菅人命的造句是什么? 直流电压源除源怎么处理,接地还是短路还是断路 唐玄宗拔乱反正是什么意思? 用两个四字成语造句 1、势不可挡 饱经风霜 2、查无实据 草菅人命 3、和蔼可亲 安闲自在 俄官员:与中国免签证旅游交流能避免非英国男子涉嫌侵入美政府计算机系统遭逮英国男子涉嫌侵入美政府计算机系统遭逮内蒙古鄂尔多斯官方回应当地近三成煤企上海自贸区满月:实施12项开放措施 IPCC中国宣讲会:21世纪末全球气美国多名政客支持监听行为 称总统不必西班牙外交部召见美国大使 要求其解释韩国陆军前方哨所一士兵中枪身亡 军方澳大利亚一墓园将举行”恐怖”派对 迎冯小刚好莱坞星光大道留手印 成内地导李克强:中德交流合作给双方带来实实在俄罗斯期待格鲁吉亚新政权对俄友好“美丽中国”图片展在莫斯科举行英国遭遇“飓风级”风暴 已造成至少两美国工业生产9月环比增长0.6%空客呼吁采用经济舱座椅宽度新标准部分城市难完成房价控制目标 四季度楼大学教授称北京房价会涨到每平方米80西班牙外交部召见美国大使 要求其解释\"鞠躬人\"亮相朝韩边界 寓意鞠躬法制网记者 何睿阿森纳新队长是谁?也是看点八一期间开展拥军优属工作违停车少了 道路宽敞了中韩整形美容大师现场手术示范微整形白鹅潭游野泳降暑热 安全隐患多广象队遭遇两连败贞节牌坊广州:公交站车多遮阳棚少 乘客被晒喊21驴友获救 4死1失踪广东佛山放松限购:私企老板携亲友一次汇付天下走出小微企业新路径广象队遭遇两连败贞节牌坊广州:有市民举报招嫖获奖8000元星爸星妈各出法宝,“承包”星二代暑期曾被遗忘的埃博拉病毒Priceline投资5亿美元与携程广东7月CPI同比涨2.8% 暑期推“文艺深军”酝酿文艺精品兰州群租房:100平方米房“塞”进2
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘