欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Delphi 編寫(xiě)DLL動(dòng)態(tài)鏈接庫文件的知識
https://www.cnblogs.com/bayzhang/p/5824478.html
一、DLL動(dòng)態(tài)鏈接庫文件的知識簡(jiǎn)介:

                  Windows的發(fā)展要求允許同時(shí)運行的幾個(gè)程序共享一組函數的單一拷貝。動(dòng)態(tài)鏈接庫就是在這種情況下出現的。動(dòng)態(tài)鏈接庫不用重復編譯或鏈接,一旦裝入內存,Dlls函數可以被系統中的任何正在運行的應用程序軟件所使用,而不必再將DLLs函數的另一拷貝裝入內存?!∪魏螒贸绦蚨伎梢怨蚕碛裳b入內存的DLLs管理的內存資源塊。只包含共享數據的DLLs稱(chēng)為資源文件。在Delphi中,一般工程文件的頭標用program關(guān)鍵字,而DLLs工程文件頭標用library 關(guān)鍵字標識(ActiveX控件也是一樣)。不同的關(guān)鍵字通知編譯器生成不同的可執行文件。用program關(guān)鍵字生成的是.exe文件,而用library關(guān)鍵字生成的是.dll等其他文件;假如要輸出供其它應用程序使用的函數或過(guò)程,則必須將這些函數或過(guò)程列在Exports子句中。而這些函數或過(guò)程本身必須用export編譯指令進(jìn)行編譯。、

使用DLL動(dòng)態(tài)鏈接庫技術(shù)主要有以下幾個(gè)原因:

1>、減少可執行文件的大??;

2>、實(shí)現資源共享;

3>、便于維護和升級

4>、比較安全

二、DLL動(dòng)態(tài)鏈接庫文件的分類(lèi):

根據DLLs完成的功能,我們把DLLs分為如下的三類(lèi):

1、完成一般功能的DLLs;

2、用于數據交換的DLLs;

3、用于窗體重用的DLLs。

三、DLL動(dòng)態(tài)鏈接庫文件的基本格式如下:

library  Project1;   // 定義DLL文件的文件名,也是庫名。和Unit差不多,會(huì )隨保存時(shí)的文件名一起改變

uses

SysUtils,

Classes,

  Unit1 in 'Unit1.pas' {Form1}, // 創(chuàng )建的窗體文件

  Unit2 in 'Unit2.pas';   // 創(chuàng )建的單元文件

Type

   // 定義自己的數據類(lèi)型

Var

   // 定義變量。

     // 自己定義的函數

function   TestDll(i:integer):integer;stdcall; // 與平時(shí)的編寫(xiě)差不多,只是多了一個(gè)stdcall參數

begin

Result := i+i;

end;

{$R *.res}  // 設置版本信息Project|options,必須有{$R *.res}才能顯示。也可以位于函數的定義之前。

     // 自己定義的函數

exports   // 將函數或過(guò)程輸出,供其他程序使用。不用寫(xiě)參數和調用后綴。函數直接用‘,‘分開(kāi);

      TestDll;

begin

end.

四、創(chuàng )建和調用DLL動(dòng)態(tài)鏈接庫的基本步驟:

1、點(diǎn)擊【File】—>【New】—>【Other】菜單項,打開(kāi)【New Items】,選擇【New】;

2、選擇【Dll Wizard】選項卡,點(diǎn)擊ok,DLL工程創(chuàng )建成功。

3、添加代碼。

4、按【Project】的【Build Project1】生成DLL動(dòng)態(tài)鏈接庫文件Project1.DLL。

5、調用DLL動(dòng)態(tài)鏈接庫文件。

                //調用程序和Project1.dll在同一個(gè)目錄中,在implementation下面寫(xiě), external后指定了Delphi.dll的位置

     1>、function TestDll(i:integer):integer;stdcall; external ‘Project1.dll’;

               //TestDll 必須跟Dll中函數名一樣,區分大小寫(xiě);Project1不區分大小寫(xiě);

     2>、使用就跟普通的函數是一樣的。  

五、編寫(xiě)DLL動(dòng)態(tài)鏈接庫時(shí),應該注意的事項:

1、在DLL中編寫(xiě)的函數或過(guò)程都必須加上stdcall調用參數。

                       在Delphi 1或Delphi 2環(huán)境下該調用參數是far。從Delphi 3以后將這個(gè)參數變?yōu)榱藄tdcall,目的是為了使用標準的Win32參數傳遞技術(shù)來(lái)代替優(yōu)化的register參數。忘記使用stdcall參數是常見(jiàn)的錯誤,這個(gè)錯誤不會(huì )影響DLL的編譯和生成,但當調用這個(gè)DLL時(shí)會(huì )發(fā)生很?chē)乐氐腻e誤,導致操作系統的死鎖。原因是register參數是Delphi的默認參

數。如果確實(shí),就會(huì )變成register了。

2、所寫(xiě)的函數和過(guò)程應該用exports語(yǔ)句聲明為外部函數。

                       正如大家看到的,TestDll函數被聲明為一個(gè)外部函數。這樣做可以使該函數在外部就能看到,具體方法是單激鼠標右鍵用“快速查看(Quick View)”功能查看該DLL文件。(如果沒(méi)有“快速查看”選項可以從Windows CD上安裝。)TestDll函數會(huì )出現在Export Table欄中。另一個(gè)很充分的理由是,如果不這樣聲明,我們如果不這樣聲明,我們編寫(xiě)的函數將不能被調用,這是大家都不愿看到的。

3、當使用了長(cháng)字符串類(lèi)型的參數、變量時(shí)要引用ShareMem,或者避免使用String類(lèi)型。

                       Delphi中的string類(lèi)型很強大,我們知道普通的字符串長(cháng)度最大為256個(gè)字符,但Delphi中string類(lèi)型在默認情況下長(cháng)度可以達到2G。(對,您沒(méi)有看錯,確實(shí)是兩兆。)這時(shí),如果您堅持要使用string類(lèi)型的參數、變量甚至是記錄信息時(shí),就要引用ShareMem單元,而且必須是第一個(gè)引用的。既在uses語(yǔ)句后是第一個(gè)引用的單元。如下例:uses  ShareMem,  SysUtils,  Classes;

                       還有一點(diǎn),在您的工程文件(*.dpr)中而不是單元文件(*.pas)中也要做同樣的工作,這一點(diǎn)Delphi自帶的幫助文件沒(méi)有說(shuō)清楚,造成了很多誤會(huì )。不這樣做的話(huà),您很有可能付出死機的代價(jià)? 避免使用string類(lèi)型的方法是將string類(lèi)型的參數、變量等聲明為Pchar或ShortString(如:s:string[10])類(lèi)型。同樣的問(wèn)題會(huì )出現在當您使用了動(dòng)態(tài)數組時(shí),解決的方法同上所述。

六、在Delphi中調用DLL:

在Delphi中調用DLL動(dòng)態(tài)鏈接庫有兩種方法:靜態(tài)調用方法、動(dòng)態(tài)調用方法;

1、靜態(tài)調用DLL動(dòng)態(tài)鏈接庫(如上面給出的格式一樣)

unit   Unit1;

interface

uses

Windows,   Messages,   SysUtils,   Classes,   Graphics, Controls,   Forms,   Dialogs,   StdCtrls;

type

TForm1   =   class(TForm)

Edit1:   TEdit;     // 編輯框(Edit)

Button1:   TButton; // 按鈕(Button)

procedure   Button1Click(Sender:   TObject);

private

{   Private   declarations   }

public

{   Public   declarations   }

end;

var

Form1:   TForm1;

implementation

{$R   *.DFM}

// 本行以下代碼為我們真正動(dòng)手寫(xiě)的代碼

function   TestDll(i:integer):integer;stdcall; external   ‘Project1.dll ';

procedure   TForm1.Button1Click(Sender:   TObject);

begin

Edit1.Text:=IntToStr(TestDll(1));

end;

end.

注意事項有以下一些:

1>、調用參數用stdcall。

       和前面提到的一樣,當引用DLL中的函數和過(guò)程時(shí)也要使用stdcall參數,原因和前面提到的一樣。

2>、用external語(yǔ)句指定被調用的DLL文件的路徑和名稱(chēng)。

       正如大家看到的,我們在external語(yǔ)句中指定了所要調用的DLL文件的名稱(chēng)。沒(méi)有寫(xiě)路徑是因為該DLL文件和調用它的主程序在同一目錄下。如果DLL文件在C:\,則我們可將上面的引用語(yǔ)句寫(xiě)為external 'C:\Delphi.dll '。注意文件的后綴.dll必須寫(xiě)上。

3>、不能從DLL中調用全局變量。

       如果我們在DLL中聲明了某種全局變量,如:var s:byte。這樣在DLL中s這個(gè)全局變量是可以正常使用的,但s不能被調用程序使用,既s不能作為全局變量傳遞給調用程序。不過(guò)在調用程序中聲明的變量可以作為參數傳遞給DLL。

4>、被調用的DLL必須存在。

       這一點(diǎn)很重要,使用靜態(tài)調用方法時(shí)要求所調用的DLL文件以及要調用的函數或過(guò)程等等必須存在。如果不存在或指定的路徑和文件名不正確的話(huà),運行主程序時(shí)系統會(huì )提示“啟動(dòng)程序時(shí)出錯”或“找不到*.dll文件”等運行錯誤。

2、動(dòng)態(tài)調用DLL動(dòng)態(tài)鏈接庫

只是將原來(lái)的Button1Click過(guò)程中的語(yǔ)句用下面的代碼替換掉了。

procedure   TForm1.Button1Click(Sender:   TObject);

type

TIntFunc=function(i:integer):integer;stdcall; //定義一個(gè)函數類(lèi)型

var

Th: Thandle;

Tf: TIntFunc;

Tp: TFarProc;

begin

Th := LoadLibrary( ‘Project1.dll');   // 裝載DLL文件

if Th>0   then

try

Tp:=GetProcAddress(Th,PChar(‘TestDll’)); // 查找函數的位置

if   Tp<>nil then  

begin

Tf := TIntFunc(Tp);

Edit1.Text := IntToStr(Tf(1));   // 調用TestC函數

end

else

ShowMessage(‘TestDll函數沒(méi)有找到 ');

Finally

FreeLibrary(Th);   // 釋放DLL,否則會(huì )一直占用內存,知道退出windows或關(guān)機為止;

End

else

ShowMessage( 'Project1.dll沒(méi)有找到 ');

end;

                      大家已經(jīng)看到了,這種動(dòng)態(tài)調用技術(shù)很復雜,但只要修改參數,如修改LoadLibrary( 'Project1.dll ')中的DLL名稱(chēng)為'Delphi.dll '就可動(dòng)態(tài)更改所調用的DLL。

注意的事項有以下:

1>、定義所要調用的函數或過(guò)程的類(lèi)型。

        在上面的代碼中我們定義了一個(gè)TIntFunc類(lèi)型,這是對應我們將要調用的函數TestDll的。在其他調用情況下也要做同樣的定義工作。并且也要加上stdcall調用參數。

2>、釋放所調用的DLL。

        我們用LoadLibrary動(dòng)態(tài)的調用了一個(gè)DLL,但要記住必須在使用完后手動(dòng)地用FreeLibrary將該DLL釋放掉,否則該DLL將一直占用內存直到您退出Windows或關(guān)機為止。

3、兩種調用方法之間的優(yōu)缺點(diǎn):

                       靜態(tài)方法實(shí)現簡(jiǎn)單,易于掌握并且一般來(lái)說(shuō)稍微快一點(diǎn),也更加安全可靠一些;但是靜態(tài)方法不能靈活地在運行時(shí)裝卸所需的DLL,而是在主程序開(kāi)始運行時(shí)就裝載指定的DLL直到程序結束時(shí)才釋放該DLL,另外只有基于編譯器和鏈接器的系統(如Delphi)才可以使用該方法。

                       動(dòng)態(tài)方法較好地解決了靜態(tài)方法中存在的不足,可以方便地訪(fǎng)問(wèn)DLL中的函數和過(guò)程,甚至一些老版本DLL中新添加的函數或過(guò)程;但動(dòng)態(tài)方法難以完全掌握,使用時(shí)因為不同的函數或過(guò)程要定義很多很復雜的類(lèi)型和調用方法。對于初學(xué)者,筆者建議您使用靜態(tài)方法,待熟練后再使用動(dòng)態(tài)調用方法。

七、使用DLL的實(shí)用技巧:

1、編寫(xiě)技巧:

1>、為了保證DLL的正確性,可先編寫(xiě)成普通的應用程序的一部分,調試無(wú)誤后再從主程序中分離出來(lái),編譯成DLL。

2>、為了保證DLL的通用性,應該在自己編寫(xiě)的DLL中杜絕出現可視化控件的名稱(chēng),如:Edit1.Text中的Edit1名稱(chēng);或者自

         定義非Windows定義的類(lèi)型,如某種記錄。

3>、為便于調試,每個(gè)函數和過(guò)程應該盡可能短小精悍,并配合具體詳細的注釋。

4>、應多利用try-finally來(lái)處理可能出現的錯誤和異常,注意這時(shí)要引用SysUtils單元。

5>、盡可能少引用單元以減小DLL的大小,特別是不要引用可視化單元,如Dialogs單元。例如一般情況下,我們可以不

         引用Classes單元,這樣可使編譯后的DLL減小大約16Kb。

2、調用技巧:

1>、在用靜態(tài)方法時(shí),可以給被調用的函數或過(guò)程更名。改寫(xiě)引用函數為

          function   TestC(i:integer):integer;stdcall; external   'Project1.dll '     name   'TestDll ';

         其中name的作用就是重命名(原名稱(chēng)仍然大小寫(xiě)敏感)。 

         直接通過(guò)名稱(chēng)調用(注意名稱(chēng)大小寫(xiě)敏感)。     

         function   TestDll (i:integer):integer;stdcall; external   'Project1.dll '   ;

         //  如果定義了Index就可以使用,通過(guò)索引號調用。程序中可以用與DLL中不一樣的名稱(chēng).

        procedure   test2;external   'Project1.dll'   index   1;  // exports   TestDll    index   1;  

2>、可把我們編寫(xiě)的DLL放到Windows目錄下或者Windows\system目錄下。這樣做可以在external語(yǔ)句中或LoadLibrary

         語(yǔ)句中不寫(xiě)路徑而只寫(xiě)DLL的名稱(chēng)。但這樣做有些不妥,這兩個(gè)目錄下有大量重要的系統DLL,如果您編的DLL與

         它們重名的話(huà)其后果簡(jiǎn)直不堪設想.

3、調試技巧:

1>、我們知道DLL在編寫(xiě)時(shí)是不能運行和單步調試的。有一個(gè)辦法可以,那就是在Run|parameters菜單中設置一個(gè)宿

         主程序。在Local頁(yè)的Host Application欄中添上宿主程序的名字。宿主程序是使用它生成的DLL包的程序。然后

         再DLL工程中點(diǎn)擊【Run】就可進(jìn)行單步調試、斷點(diǎn)觀(guān)察和運行了。

2>、添加DLL的版本信息。如果包含了版本信息,DLL的大小會(huì )增加2Kb。增加這么一點(diǎn)空間是值得的。很不幸我們如

         果直接使用Project|options菜單中Version選項是不行的,還必須增加{$R *.res},才會(huì )顯示版本信息;

3>、為了避免與別的DLL重名,在給自己編寫(xiě)的DLL起名字的時(shí)候最好采用字符數字和下劃線(xiàn)混合的方式。如:jl_try16.dll。

八、具體的一個(gè)例子:用DLL文件封裝窗體的實(shí)現方法實(shí)例:

                       一個(gè)程序不再是單一的一個(gè)EXE文件了,而是由一個(gè)EXE文件加N個(gè)DLL文件組成,這樣做的原因是方

便以后的維護與更新,也是跨平臺開(kāi)發(fā)的重要一步。

1、打開(kāi)DELPHI,新建一個(gè)Dll Wizard

2、 在新建的Dll里新建一個(gè)Form

3、 在新建的Form里uses stdctrls

4、 在var下面寫(xiě):

        Procedure synapp(App:THandle);stdcall;

        Procedure showform;stdcall;

5、然后在implementation 下面uses math

6、 在{$R *.dfm}下面寫(xiě)

Procedure synapp(App:THandle);stdcall;
Begin
  Application.Handle:=app;// 防止每顯示一個(gè)窗體,就在任務(wù)欄中顯示一個(gè)圖標
End;

Procedure showform;stdcall;
Begin
  Form1:=Tform1.create(application);
  Form1.show;
End;

7 、在dll的Library文件里的{$R *.res}下面寫(xiě):

exports
Sysapp,show;
上面到此為止完成了DLL封裝窗體的創(chuàng )建

8、下面是調用了

1> 、 在要調用DLL文件的程序的var下寫(xiě):

Procedure synapp(App:THandle);stdcall;external ‘my.dll’ ;//----你的DLL文件名

Procedure showform;stdcall;external‘my.dll’;//----你的DLL文件名

注:把你寫(xiě)好的DLL放在本程序的同一目錄下,和上面一樣,要uses math;

2> 、在你的程序的Button的On Click事件下寫(xiě):

Synapp(applicatiln.Handle);

Showform;

完畢

                       用DLL文件封裝窗體,每一個(gè)DLL工程中的窗體都是獨立的一個(gè)進(jìn)程。所以任何操作都是獨立的。在DLL

工程中使用RegisterClass方法對窗體進(jìn)行祖冊是,在應用程序工程或者其他工程再用FindClass方法查找這個(gè)類(lèi)是無(wú)

效的。而對于DLL工程而言,方法指針的傳遞非常的安全,所以可以維護一個(gè)指針列表,用于指向各個(gè)DLL工程中

FindClass方法的地址。在需要查找窗體類(lèi)時(shí),對所以的DLL工程的FindClass方法進(jìn)行調用即可。

                       封裝在DLL工程中的窗體,每打開(kāi)一次窗體就會(huì )出現一個(gè)圖標在任務(wù)欄區。為了解決這個(gè)問(wèn)題,應在調用

DLL文件時(shí),將應用程序中的Application對象和Screen對象傳到DLL工程中,并替換DLL工程中這兩個(gè)對象。

 

轉自:http://blog.csdn.net/zang141588761/article/details/51248258

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
開(kāi)使你的第一個(gè)DLL
delphi dll 調用技巧
Delphi DLL的創(chuàng )建、靜態(tài) 以及動(dòng)態(tài)調用
C#調用DLL錯誤:PInvokeStackImbalance。
dll 導出函數名的那些事
Delphi深入DLL編程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久