DELPHI的BPL使用
了解BPL和DLL的關(guān)系將有助于我們更好地理解DELPHI在構(gòu)件制作、運(yùn)用和動(dòng)態(tài)、靜態(tài)編譯的工作方式。對(duì)初學(xué)DELPHI但仍對(duì)DELPHI開發(fā)不甚清晰的朋友有一定幫助。
第一部分:有關(guān)包的介紹
一般我們編寫編譯一個(gè)DELPHI應(yīng)用程序時(shí),會(huì)產(chǎn)生一個(gè)EXE文件,也就是一個(gè)獨(dú)立的WINDOWS應(yīng)用程序。很重要的一點(diǎn):區(qū)別于Visual Basic,DELPHI產(chǎn)生的是預(yù)先包裹的應(yīng)用程序是不需要大量的運(yùn)行庫(DLL's)。
假設(shè):打開Delphi默認(rèn)的工程(只有一個(gè)空白form),F(xiàn)9她將編譯生成一個(gè)大約295 KB (Delphi 5)的可執(zhí)行文件。然后打開Project | Options,把‘Build with runtime packages’選上再編譯一下,EXE文件大小就只有15 KB左右了。
我們編譯一個(gè)DELPHI應(yīng)用程序時(shí)默認(rèn)地沒有選擇'Build with runtime packages',編譯器將把程序運(yùn)行所需要的代碼直接寫入你的EXE文件中,因此產(chǎn)生的程序是一個(gè)相對(duì)獨(dú)立的程序,并不需要任何附屬的支持文件(例如動(dòng)態(tài)運(yùn)行庫文件DLL),這也就知道了為什么DELPHI產(chǎn)生的應(yīng)用程序?yàn)槭裁炊寄敲创蟆?br /> 要建立盡可能小的DELPHI程序,方法之一就要充分發(fā)揮Borland package libraries的作用,簡(jiǎn)稱BPL。
先說什么是包?
簡(jiǎn)而言之,一個(gè)包就是一個(gè)在DELPHI的IDE環(huán)境中被DELPHI應(yīng)用程序共享的特殊的動(dòng)態(tài)鏈接庫。包允許我們通過多級(jí)應(yīng)用將我們的程序的一部分當(dāng)做一個(gè)分離的模塊供其他應(yīng)用程序來共享。
包大致可分為運(yùn)行期包(Run-time packages)和設(shè)計(jì)期包(Design-time packages):
運(yùn)行期包-當(dāng)運(yùn)行程序時(shí)提供VCL和庫函數(shù)的支持,操作上很類似標(biāo)準(zhǔn)的動(dòng)態(tài)鏈接庫。
設(shè)計(jì)期包-用來在DELPHI的IDE環(huán)境安裝控件和為控件建立特殊的屬性編輯器。設(shè)計(jì)期包允許包含控件、屬性和控件編輯器等等,在IDE環(huán)境中,這類包是程序設(shè)計(jì)所必需的,也僅僅是DELPHI使用,并不和開發(fā)的應(yīng)用程序一起分發(fā)。
知道這些包的運(yùn)用,我們也就知道了運(yùn)行期包是如何做處理和它們對(duì)DELPHI程序員有什么幫助了。
有一點(diǎn)必須說明:想很好地運(yùn)用包并不要求你先成為一個(gè)成熟的控件編寫者。DELPHI編程初學(xué)者也可以和應(yīng)該嘗試去接觸包的概念,這將有利于你更好地理解包和DELPHI的工作關(guān)系。
第二部分:適時(shí)運(yùn)用包裹和DLL
一般都認(rèn)為加入WINDOWS操作系統(tǒng)中的動(dòng)態(tài)運(yùn)行庫是一種最有用最高效的應(yīng)用。在WINDOWS系統(tǒng)中,很多應(yīng)用程序同時(shí)運(yùn)行可能會(huì)引起了內(nèi)存方面的問題,很多程序執(zhí)行相似的操作任務(wù),但各自又由不同的代碼來控制并完成任務(wù),動(dòng)態(tài)運(yùn)行庫的作用就是將你的執(zhí)行程序中的這些代碼放到一個(gè)系統(tǒng)共享環(huán)境下的DLL中去。可能最為直觀的動(dòng)態(tài)鏈接庫例子就是WINDOWS操作系統(tǒng)自己和它本身所帶的API了。
動(dòng)態(tài)鏈接庫通常都是用來集合過程(procedure)和函數(shù)(function)以供程序調(diào)用。當(dāng)然我們?cè)诰帉憚?dòng)態(tài)鏈接庫的同時(shí),也可以把一個(gè)DELPHI FORM放到一個(gè)DLL中去(例如一個(gè)AboutBox FORM),此外我們也可以在DLL中存儲(chǔ)程序所需要的資源(resources)。更多關(guān)于DELPHI如何操作使用動(dòng)態(tài)鏈接庫,請(qǐng)參考相關(guān)書籍,不再贅述。
在比較DLLs 和BPLs之前,我們先要知道可執(zhí)行文件的2種代碼鏈接的方式:靜態(tài)鏈接和動(dòng)態(tài)鏈接。
靜態(tài)鏈接就是當(dāng)一個(gè)DELPHI工程被編譯的時(shí)候,工程所需要的所有代碼將被直接鏈接入你的程序執(zhí)行文件。結(jié)果就是執(zhí)行文件將包含程序所需要使用到的所有單元(units),你也許會(huì)說這樣代碼有點(diǎn)冗長,因?yàn)樵谕ǔDJ(rèn)情況下,一個(gè)FORM單元的uses子句列舉了至少5個(gè)基本單元(如:Windows, Messages, SysUtils,...),盡管如此,DELPHI還是能夠智能地自動(dòng)鏈接單元中真正要用到的代碼到工程代碼中,從而盡可能地減少了執(zhí)行文件的大小。使用靜態(tài)鏈接,我們的應(yīng)用程序就是一個(gè)相對(duì)獨(dú)立的程序,不需要任何額外的支持文件或動(dòng)態(tài)鏈接庫(暫時(shí)不考慮BDE和ActiveX構(gòu)件)。DELPHI中默認(rèn)使用的就是靜態(tài)鏈接方式。
動(dòng)態(tài)鏈接就是應(yīng)用程序?qū)⒑蜆?biāo)準(zhǔn)的動(dòng)態(tài)鏈接庫(DLLs)一起運(yùn)行。動(dòng)態(tài)鏈接方式不需要將代碼直接建立到每個(gè)應(yīng)用程序中去,單獨(dú)為多個(gè)應(yīng)用程序提供多線程的庫函數(shù)支持,任何程序運(yùn)行期間才需用到的包才將被加載,更值得一提的是:程序在動(dòng)態(tài)方式需要調(diào)用的包是自動(dòng)加載的,因此你不需要專門寫加載包的代碼。
方法:簡(jiǎn)單地選中在Project | Options 對(duì)話框中'Build with runtime packages'復(fù)選框后,再次編譯你的程序,你的程序代碼將自動(dòng)鏈接到動(dòng)態(tài)運(yùn)行包,而不是將引用單元都靜態(tài)鏈接入你的工程執(zhí)行文件。
是選擇BPL 還是 DLL?區(qū)別又在哪里?
你可能很奇怪為什么要選擇使用運(yùn)行期包,而不是DLL,或者還有其他什么方法。
相對(duì)于DLL而言,包裹的概念是DELPHI開發(fā)中所特有的,就是說其他語言編寫的應(yīng)用程序不能引用DELPHI建立的包裹。即使包是一種被DELPHI編寫的應(yīng)用程序所使用的動(dòng)態(tài)鏈接庫,它也同時(shí)提供給了DELPHI程序員更多的庫函數(shù)支持。
通常我們?cè)贒ELPHI中建立動(dòng)態(tài)鏈接庫(DLLs)是用來存儲(chǔ)不同環(huán)境下應(yīng)用程序所需要使用到的過程和函數(shù),而包不僅能夠包含代碼單元(untits)、構(gòu)件和FORMs,還能包含DELPHI中的類(classes)-這就使我們能夠在其中引用對(duì)象向?qū)Ь幋a(object oriented code)。在包裹中,我們可以保存完整的通用DELPHI構(gòu)件,而動(dòng)態(tài)運(yùn)行庫(DLL's)對(duì)此則無能為力了。
此外,在縮減程序代碼上,DLLs和BPLs扮演著同樣重要的角色,其主要原因就是在使用包裹或動(dòng)態(tài)鏈接庫技術(shù)后,都直接地減少了程序的文件大小。當(dāng)然,還要說明的是:執(zhí)行程序需要加載的DLLs或BPLs也可能會(huì)是很龐大的。例如如果需要分發(fā)你的包裹文件(主要是VCL包,vcl50.BPL)至少有2MB左右。
盡管如此,如果你是要分發(fā)共享同個(gè)包的多個(gè)應(yīng)用程序,你就可以省很多事了。當(dāng)用戶方系統(tǒng)中已經(jīng)存在程序運(yùn)行需要的部分文件(如:標(biāo)準(zhǔn)的DELPHI BPLs)后,就只需要下載程序的最小執(zhí)行文件了。如果你的程序工程主要是通過INTERNET等方式分發(fā)和開展,那效率顯然有很大的提高。
同時(shí),包的應(yīng)用也節(jié)省系統(tǒng)內(nèi)存,因?yàn)閯?dòng)態(tài)鏈接的結(jié)果就是:只有一個(gè)VCL被讀入內(nèi)存供所有使用運(yùn)行期包的DLEPHI應(yīng)用程序使用。
包裹的版本問題
當(dāng)你想升級(jí)你的動(dòng)態(tài)鏈接庫時(shí)(改變其中一些執(zhí)行函數(shù)),你可以簡(jiǎn)單地編譯產(chǎn)生新的程序文件,并上載新版本文件,所有正在使用該動(dòng)態(tài)鏈接庫的應(yīng)用程序仍將工作(除非你已經(jīng)將存在的舊版本程序去除)。
換個(gè)角度來講,在升級(jí)新包裹文件的同時(shí),不要忘記升級(jí)程序的執(zhí)行文件。正如你所了解的,包裹文件就是一個(gè)單元文件(units)的集合,所有編譯過的單元文件(DCU)都含有版本信息,因此,除非我們有單元文件的源碼(source),否則我們不能在DELPHI4或5中使用編譯過的單元,所以一旦我們改變了單元文件中接口部分uses子句中列舉出的任一單元文件,該文件就需要重新編譯。編譯器將檢查DCU文件的版本信息,并決定單元是否需要重新編譯。因此我們不能在DELPHI5編譯的應(yīng)用程序中使用在DELPHI6下編譯的包,任何為你的應(yīng)用程序服務(wù)的包和你的應(yīng)用程序必須在相同環(huán)境下編譯。
因此,當(dāng)給包裹命名的時(shí)要保留包裹名中包含有DELPHI的版本信息(如'AboutDP50',其中50就代表Delphi 5)。這可以有效防止文件版本的沖突問題,也可以避免很多不必要的麻煩,包使用者可以更清楚包的版本和包裹適用于哪個(gè)DELPHI編譯器。
如果你要分發(fā)運(yùn)行期或設(shè)計(jì)期包給其他DELPHI程序員,建議同時(shí)提供了.DCP(含有包的頭信息和各個(gè)單元文件)和.BPL文件,還有包中所包含的所有單元文件的.DCU文件。
第三部分:建立和使用運(yùn)行期包
建立一個(gè)包裹
建立一個(gè)包很簡(jiǎn)單,但在建包之前要做一些準(zhǔn)備工作。首先,你需要知道你準(zhǔn)備建立哪種類型的包文件:運(yùn)行期包還是設(shè)計(jì)期包,或兩者都是;其次是,建立、調(diào)試,反復(fù)地測(cè)試你想放置到包中去的單元文件;最后,為建立的包裹文件命名,還有就是選擇一個(gè)合適的地方來存放文件。
建立一個(gè)新的運(yùn)行期包,按照以下步驟:
啟動(dòng)DELPHI,并選擇File | Close All關(guān)閉默認(rèn)的工程。
選擇File | New...,在"New items"對(duì)話框中的"new"頁面中雙擊Package圖標(biāo)(如圖),就會(huì)出現(xiàn)包裹編輯器(如圖):包裹編輯器包含2個(gè)文件夾:Contains和Requires。
點(diǎn)擊Add按鈕,可以增加一個(gè)單元文件(構(gòu)件或是一個(gè)簡(jiǎn)單的代碼單元文件)。注意:你添加的是PAS源碼文件而不是編譯后的DCU文件。當(dāng)你添加單元文件的同時(shí),包中的單元的名字就顯示在包裹編輯器的Contains文件夾中了。如圖中添加了FindFile和PictureClip的單元文件。
打開Requires文件夾,展開的列表表示包裹所需要的包的DCP文件,包裹文件最基本的就需要引用含有絕大部分標(biāo)準(zhǔn)可視控件的vcl50.dcp文件。
當(dāng)你添加完單元文件,單擊Options按鈕,在Description面板中的Usage options組中你需要選擇包裹種類:是設(shè)計(jì)期包,還是運(yùn)行期包,或者兩者都是。如果選擇Runtime only(僅運(yùn)行期包),其他包的使用者將無法將圖示2個(gè)構(gòu)件安裝到IDE環(huán)境中去。
使用File | Save保存包工程文件(DPK),然后保存包文件,如AboutDP50,包裹文件的命名將很重要。
在包裹器中,單擊Compile按鈕來編譯包。
如果不出什么意外,編譯包后將建立一個(gè)包裹文件(BPL文件),期間你可能還要確定你必須增加的其他包裹(例如VCLX50),這些包都將在Requires文件夾中列出。
完成,Borland package library文件已經(jīng)成功建立,就等著使用了。
在包裹編輯器中有一個(gè)Install按鈕,就是用來將當(dāng)前包裹安裝成一個(gè)設(shè)計(jì)期包的。如果包裹是run-time only(僅運(yùn)行期包),那Install按鈕將無法使用。
關(guān)于所建立的這些文件
除了DPK文件和那些單元源碼文件,DELPHI還使用包裹的動(dòng)態(tài)鏈接版本產(chǎn)生一個(gè)BPL文件和一個(gè)含有包內(nèi)標(biāo)識(shí)信息DCP文件,DCP文件就是包中所包含單元文件的編譯文件(DCU)的標(biāo)識(shí)信息的集合。
使用運(yùn)行期包設(shè)計(jì)程序
開始使用動(dòng)態(tài)鏈接編寫應(yīng)用程序時(shí),不需要寫代碼去加載運(yùn)行期包裹,只需要在Project | Options中做相關(guān)設(shè)置,選擇在Packages頁的Runtime Packages編輯框中的包裹列表,編譯程序時(shí)將自動(dòng)鏈接。應(yīng)用程序要使用到一個(gè)運(yùn)行期包時(shí),使用ADD按鈕來增加包裹文件。
注意:盡管一個(gè)應(yīng)用程序被鏈接到運(yùn)行期包,程序的USES子句所列出的單元文件也必須都是存在的,編譯運(yùn)行期包裹只是告訴應(yīng)用程序哪里可以找到構(gòu)件代碼而已。
當(dāng)配置一個(gè)使用到運(yùn)行期包裹的應(yīng)用程序時(shí),確定用戶擁有可執(zhí)行文件和程序所需的庫文件(.BPL或.DLL)。如果庫文件在和EXE文件不同的目錄下,必須將其指定到系統(tǒng)所能到達(dá)的目錄。因此,最好的選擇就是WindowsSystem系統(tǒng)目錄。
總而言之
包裹使你能夠有彈性地選擇應(yīng)用程序的分發(fā)方式,也使構(gòu)件的安裝變簡(jiǎn)單了,此外,使用包裹也減少了應(yīng)用程序的文件大小,因此,使用包裹的開發(fā)方式還是具有不小的意義的。
總結(jié)
以上是生活随笔為你收集整理的DELPHI的BPL使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 古风浪漫的爱情句子158个
- 下一篇: 小班教案《宝贝厨房》