請問如何用Delphi6.0 call vc++6.0寫的DLL檔 |
尚未結案
|
per_k
一般會員 發表:8 回覆:10 積分:3 註冊:2002-07-16 發送簡訊給我 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
參考看看 此為轉貼資料
肖運勇 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”屬性均設?空): 最後設計的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下程式組織的一種重要方式,使用動態連結程式庫可以極大地保護用戶在不同開發工具、不同時期所做的工作;利用動態連結程式庫,用戶可以逐步去構築自己的程式模組庫,?今後的工作積累素材 發表人 - jackkcg 於 2002/10/23 11:48:18
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
JS
一般會員 發表:22 回覆:26 積分:9 註冊:2002-07-20 發送簡訊給我 |
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: 各位好,我用了JACK先進的方法測試後(用Delphi測試),是可以得到結果的,但是最後卻會出現access violation at 0xXXXX的錯誤!不知為何?可否請前輩們指導一下為什麼? per_k 你好: 一般來說,動態載入某個 DLL 中的 function 會產生 Access Violation,應 該是以下幾種情形 (1)你是否確定此 DLL 中的 function spec,你要 call 的 function 是否真的 存在?? (2)你要 call 的 function 中某個參數,是不是應該先要配置記憶體,如果忘 記配置記憶體的話,一定會造成 Access Violation 的 如果你能夠直接詢問這個 DLL 的作者,那是最好不過的了,最重要的,就是先 確定以上所提到的重要資訊-- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |