程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 用Delphi制作DLL小結

用Delphi制作DLL小結

編輯:Delphi
  一 Dll的制作一般分為以下幾步:
  1 在一個DLL工程裡寫一個過程或函數
  2 寫一個Exports關鍵字,在其下寫過程的名稱。不用寫參數和調用後綴。
  二 參數傳遞
  1 參數類型最好與window C++的參數類型一致。不要用Delphi的數據類型。
  2 最好有返回值[即使是一個過程],來報出調用成功或失敗,或狀態。成功或失敗的返回值最好為1[成功]或0[失敗].一句話,與Windows c++兼容。
  3 用stdcall聲明後綴。
  4 最好大小寫敏感。
  5 無須用far調用後綴,那只是為了與Windows 16位程序兼容。
  
  三 DLL的初始化和退出清理[如果需要初始化和退出清理]
  1 DLLProc[SysUtils單元的一個Pointer]是DLL的入口。在此你可用你的函數替換了它的入口。但你的函數必須符合以下要求[其實就是一個回調函數]。如下:
  procedure DllEnterPoint(dwReason: DWord);far;stdcall;
  dwReason參數有四種類型:
  DLL_PROCESS_ATTACH:進程進入時
  DLL_PROCESS_DETACH進程退出時
  DLL_THREAD_ATTACH 線程進入時
  DLL_THREAD_DETACH 線程退出時
  在初始化部分寫:
  DLLProc := @DLLEnterPoint;
  DllEnterPoint(DLL_PROCESS_ATTACH);
  2 如Form上有TdcomConnection組件,就Uses Activex,在初始化時寫一句CoInitialize (nil);
  3 在退出時一定保證DcomConnection.Connected := False,並且數據集已關閉。否則報地址錯。
  
  四 全局變量的使用
  在widnows 32位程序中,兩個應用程序的地址空間是相互沒有聯系的。雖然DLL在內存中是一份,但變量是在各進程的地址空間中,因此你不能借助dll的全局變量來達到兩個應用程序間的數據傳遞,除非你用內存映像文件。
  
  五 調用靜態載入
  1 客戶端函數聲名:
  1)大小寫敏感。
  2)與DLL中的聲明一樣。
  如: showform(form:Tform);Far;external'yproject_dll.dll';
  3)調用時傳過去的參數類型最好也與Windows c++一樣。
  4)調用時DLL必須在windows搜索路徑中,順序是:當前目錄;Path路徑;windows;widowssystem;Windowsssystem32;
  
  六 調用動態載入
  1 建立一種過程類型[如果你對過程類型的變量只是一個指針的本質清楚的話,你就知道是怎麼回事了]。如:
  type
  mypointer=procedure(form:Tform);Far;external;
  var
  Hinst:Thandle;
  showform:mypointer;
  begin
  Hinst:=loadlibrary('yproject_dll');//Load一個Dll,按文件名找。
  showform:=getprocaddress(Hinst,'showform');//按函數名找,大小寫敏感。如果你知道自動化對象的本質就清楚了。
  showform(application.mainform);//找到函數入口指針就調用。
  Freelibrary(Hinst);
  end;
  
  七 在DLL建立一個TForM
  1 把你的Form Uses到Dll中,你的Form用到的關聯的單元也要Uses進來[這是最麻煩的一點,因為你的Form或許Uses了許多特殊的單元或函數]
  2 傳遞一個Application參數,用它建立Form.
  
  八 在DLL中建立一個TMDIChildForM
  1 Dll中的MDIForm.FormStyle不用為fmMDIChild.
  2 在CreateForm後寫以下兩句:
  function ShowForm(mainForm:TForm):integer;stdcall
  var
  Form1: TForm1;
  ptr:PLongInt;
  begin
  ptr:=@(Application.MainForm);//先把dll的MainForm句柄保存起來,也無須釋放,只不過是替換一下
  ptr^:=LongInt(mainForm);//用主調程序的mainForm替換DLL的MainForm。MainForm是特殊的WINDOW,它專門管理Application中的Forms資源.
  //為什麼不直接Application.MainForm := mainForm,因為Application.MainForm是只讀屬性
  Form1:=TForm1.Create(mainForm);//用參數建立
  end;
  備注:參數是主調程序的Application.MainForm
  
  九 示例:
  DLL源代碼:
  library Project2;
  
  uses
  SysUtils,
  Classes,
  Dialogs,
  Forms,
  Unit2 in 'Unit2.pas' {Form2};
  
  {$R *.RES}
  var
  ccc: Pchar;
  
  procedure OpenForm(mainForm:TForm);stdcall;
  var
  Form1: TForm1;
  ptr:PLongInt;
  begin
  ptr:=@(Application.MainForm);
  ptr^:=LongInt(mainForm);
  Form1:=TForm1.Create(mainForm);
  end;
  
  procedure InputCCC(Text: Pchar);stdcall;
  begin
  ccc := Text;
  end;
  
  procedure ShowCCC;stdcall;
  begin
  ShowMessage(String(ccc));
  end;
  
  exports
  OpenForm;
  InputCCC,
  ShowCCC;
  begin
  end.
  
  調用方源代碼:
  unit Unit1;
  
  interface
  
  uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
  
  type
  TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  Edit1: TEdit;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  end;
  
  var
  Form1: TForm1;
  
  implementation
  
  {$R *.DFM}
  procedure OpenForm(mainForm:TForm);stdcall;External'project2.dll';
  procedure ShowCCC;stdcall;External'project2.dll';
  procedure InputCCC(Text: Pchar);stdcall;External'project2.dll';
  
  procedure TForm1.Button1Click(Sender: TObject);
  var
  Text: Pchar;
  begin
  Text := Pchar(Edit1.Text);
  // OpenForm(Application.MainForm);//為了調MDICHILD
  InputCCC(Text);//為了實驗DLL中的全局變量是否在各個應用程序間共享
  end;
  
  procedure TForm1.Button2Click(Sender: TObject);
  begin
  ShowCCC;//這裡表明Windows 32位應用程序DLL中的全局變量也是在應用程序地址空間中,16位應用程序或許不同,沒有做實驗。
  end;
  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved