Delphi以其獨特的面向控件的開發方式、強大的數據庫功能、快速的編譯技術以及簡單易學的編程特性,使得它自發布之日起即格外引人注目,許多程序員也因此將它作為首選的開發工具。然而,Delphi在科學計算、低端編程等方面的功能不如VC++。VC++功能強大、齊全,但是整個系統比較復雜、龐大,尤其對于初學者來說比較難學,其用戶界面的開發遠不如Delphi那樣方便、快捷。那么,我們能否將兩者的優點結合起來呢?答案是肯定的!具體做法是:將涉及到比較低級的操作、計算等方面的程序用VC++寫成函數放在動態鏈接庫中,而涉及到界面及與用戶交互的編程則用Delphi來實現,最后只需在Delphi中調用VC++編寫的動態鏈接庫即可。 一、動態鏈接庫簡介 動態鏈接庫(DLL,即 “Dynamic-Link Library”)是一個能夠被應用程序和其它的DLL調用的過程和函數的集合體,它里面包含的是公共代碼或資源。DLL是Windows的基石,所有的Win32 API函數都包含在DLL中。 使用DLL有許多優點: 1、一個DLL可以提供給不同的程序使用,如果有多個程序使用相同的DLL,也只需將DLL在內存中裝載一次,這樣就節省了內存開銷。 2、DLL可以使我們的編程更加模塊化,將功能相對獨立的模塊編成一個動態鏈接庫,這樣改動程序時不需將整個程序重新編譯,只需重新編譯所改動的模塊。 3、使用了DLL組件包可以大大減小可執行文件的規模。 4、對于一個大型的、不斷更新的應用程序,可以將許多重復的功能寫成DLL,用主程序調用,這樣既減少了開發的工作量,又提高了訪問速度。 5、DLL獨立于編程語言,大多數WINDOWS編程環境都允許主程序調用DLL中的函數。即可以用VC++、VB、PowerBuilder、Delphi、匯編語言等建立DLL,然后在不同語言編制的應用程序中調用它。這樣就給多人使用不同的編程語言開發項目提供了極大的方便。
二、在Delphi中調用VC++創建的動態鏈接庫的實例 (一)實驗環境 本實例的編程工具及運行環境為:Windows 98,VC++6.0,Delphi 5.0 。 (二)實驗內容 1.用VC++6.0建立一個動態鏈接庫MaxMin.DLL,該庫中包含有兩個函數:返回三個整數中最大整數的函數Max1( )和返回三個整數中最小整數的函數Min1( )。 2.用Delphi編寫測試程序調用動態鏈接庫MaxMin.DLL中的兩個函數。 (三)實驗步驟 1.用VC++6.0建立動態鏈接庫MaxMin.DLL 第一步:啟動VC++6.0,選擇“File/New/MFC AppWizzard(Dll)”,工程名設為“MaxMin”,按“確定”鈕后,選擇“Regular DLL Using shared MFC DLL”,按“Finish”鈕后,即創造了一個DLL的框架工程。 第二步:選擇“File/New”,在出現的對話框中選擇“C/C++ Header File”,在文件名處輸入“MyDLL”,按“確定”鈕,即創建了一個空的頭文件“MyDLL.h”。在該文件中輸入以下兩行內容: extern "C" _declspec(dllexport) int Min1(int x,int y,int z); extern "C" _declspec(dllexport) int Max1(int x,int y,int z); 選擇“File/Save”保存該文件的內容。 第三步:選擇“File/New”,在出現的對話框中選擇“C/C++ Source File”, 在文件名處輸入“MyDLL”,按“確定”鈕,即創建了一個空的源文件“MyDLL.cpp”。在該文件中輸入以下內容: #include "stdafx.h" #include "MyDll.h" extern "C" __declspec(dllexport) int Min1(int x,int y,int z) { if ((x<=y) & (x<=z)) return x; else if ((y<=x) & (y<=z)) return y; else return z; /*找出x,y,z中的最小整數*/ }
extern "C" __declspec(dllexport) int Max1(int x,int y,int z) { if ((x>=y) & (x>=z)) return x; else if ((y>=x) & (y>=z)) return y; else return z; /*找出x,y,z中的最大整數*/ } 選擇“File/Save”保存該文件的內容。 第四步:按下運行圖標“!”,即生成了MyDLL.DLL(在當前工程目錄的DEBUG子目錄下)。
2.用Delphi編寫調用MaxMin.DLL的測試程序 調用動態鏈接庫有兩種方法,即隱式調用和顯式調用。 (1)隱式調用 第一步:啟動Delphi,選擇“New Application”,生成一個空的應用程序,在Form的“Name”屬性處輸入“TestVcDLLForm”,Caption屬性處輸入“VC++的DLL隱式調用測試”,在Form中放入控件如表1所示(其中所有的Edit控件的“Text”屬性均設為空):
(表1:所用到的控件及其屬性)
(圖1:應用程序屏幕效果)
最后設計的Form的屏幕效果如圖1所示。選擇“File/Save all”,在“Save unit1 as”對話框中將源文件名設為“main.pas”,按“保存”鈕;在“Save Project1 as”對話框中將工程名設為“TestVcDLL”,按“保存”鈕。 第二步:選擇“File/New…”,在出現的“New Item”對話框中選擇“unit”,按“OK”鈕,生成一個空的源文件,在該文件中輸入以下內容: unit MaxMin;
interface function Min1(x,y,z:Integer):Integer; stdcall; function Max1(x,y,z:Integer):Integer; stdcall;
implementation function Min1;external 'MaxMin.DLL' name 'Min1'; function Max1;external Max'Min.DLL' name 'Max1'; end. 選擇“File/Save As…”,將上述文件存為“MaxMin.pas”。 第三步:在Main.pas文件中,在“implementation”語句后加入: uses MaxMin; 第四步:在Form上雙擊“運行”按鈕對該按鈕的“Click”事件編程,代碼如下: procedure TTestVcDLLForm.btnRunClick(Sender: TObject); begin edtMax.Text:=IntToStr(Max1(StrToInt(edtInt1.Text), StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //調用動態鏈接庫中的函數Max1 edtMin.Text:=IntToStr(Min1(StrToInt(edtInt1.Text), StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //調用動態鏈接庫中的函數Min1 end; 保存該文件。 第五步:將上述1.中VC++6所建立的動態鏈接庫“MaxMin.DLL”拷入Delphi的當前工作目錄中。 第六步:運行。結果如圖2所示。
圖2:隱式調用DLL運行結果
圖3:顯式調用DLL運行結果
(2)顯示調用 第一步:同隱式調用。只是將Form的“Caption”屬性改為“VC++的DLL顯式調用測試”。 第二步:選擇“File/New…”,在出現的“New Item”對話框中選擇“unit”,按“OK”鈕,生成一個空的源文件,在該文件中輸入以下內容: unit Unit1;
interface
type TMin1=function(x,y,z:Integer):Integer; stdcall; TMax1=function(x,y,z:Integer):Integer; stdcall; THandle=Integer;
implementation
end. 選擇“File/Save As…”,將上述文件存為“MaxMin.pas”。 第三步:在Main.pas文件中,在“implementation”語句后加入: uses MaxMin; 第四步:在Form上雙擊“運行”按鈕對該按鈕的“Click”事件編程,代碼如下: procedure TTestVcDLLForm.btnRunClick(Sender: TObject); var Handle:THandle; Min1:TMin1; Max1:TMax1; begin Handle:=LoadLibrary('MaxMin.dll'); //將“MaxMin.dll”的文件映象映射進調用進程的地址空間 if Handle<>0 then begin @Min1:=GetProcAddress(Handle,'Min1'); //取得DLL中函數Min1( )的地址 @Max1:=GetProcAddress(Handle,'Max1'); //取得DLL中函數Max1( )的地址 if (@Min1<>nil) and (@Min1<>nil) then begin edtMin.Text:=IntToStr(Min1(StrToInt(edtInt1.Text), StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //調用動態鏈接庫中的函數Min1 edtMax.Text:=IntToStr(Max1(StrToInt(edtInt1.Text), StrToInt(edtInt2.Text),StrToInt(edtInt3.Text))); //調用動態鏈接庫中的函數Max1 end else ShowMessage('調用函數“GetProcAddress”時出錯!'); FreeLibrary(Handle); //從進程的地址空間中解除“MaxMin.dll”文件的映射 end; end; 保存該文件。 第五步:將上述1.中VC++6所建立的動態鏈接庫“MaxMin.DLL”拷入Delphi的當前工作目錄中。 第六步:運行。結果如圖3所示。
以上實例均編譯通過,運行正確。
三、結束語 動態鏈接庫為不同編程環境下的應用程序之間的連接提供了方便,節省了內存,提高了速度,同時也豐富了PowerScript語言的編程能力。動態鏈接庫是Windows下程序組織的一種重要方式,使用動態鏈接庫可以極大地保護用戶在不同開發工具、不同時期所做的工作;利用動態鏈接庫,用戶可以逐步去構筑自己的程序模塊庫,為今后的工作積累素材。
|