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

Delphi采用接口實現DLL調用

編輯:Delphi

Delphi使用模塊化開發,可以采用DLL或者BPL,兩者的區別是BPL只能被同版本的Delphi使用,DLL可以被不同版本和不同開發工具的開發的軟件調用。

因此我們的軟件大多使用Delphi作為界面以及部分DLL模塊的開發工具。

DLL模塊之間通過接口方式調用。

 

1.對象創建采用工廠模式,每個DLL負責某個對象或若干個對象的創建及釋放,例如:

DLL工程為http客戶端(prjHttp.DLL)模塊,通過DLL導出的GetHttpClientFactory獲取http客戶端工廠接口,通過接口創建Http客戶端和釋放Http客戶端,工程

包括3個文件:工程文件,實現單元,接口單元。

調用此DLL的程序僅需要包含接口單元。

 

DLL工程文件

  
    System.SysUtils,   System.Classes,   utHTTPClient   
 
 
    
  .


utHttpClient示例


= 
    
     Destroy; = 
     Destroy;  CreateHttpClient( DestroyHttpClient(
    Assigned(HttpClients) ==

   Assigned(HttpClients) .

 

utHttpInterface接口文件示例


= = = = = ======  SetValue( ServerAddr: PAnsiChar;  ServerPort: Integer; = = = OnHeader( Http:IHTTPClientConnection;  Header:Pointer;  OnStartReceiveContent( Http:IHTTPClientConnection;  OnReceiveProgress( Http:IHTTPClientConnection;  OnError( Http:IHTTPClientConnection; == =  CreateHttpClient( DestroyHttpClient(


.


調用prjHttp.DLL的Delphi工程可以包含下面的單元以及上面的接口單元utHttpInterface.pas即可

將utHttpDLL.pas中的

//{$define utHttpDLL)

去掉注釋,即可以將http客戶端這些代碼包含到Delphi工程中。

//






= = == LibHandle <> INVALID_HANDLE_VALUE 
  = GetProcAddress(LibHandle,  Assigned(P) =
  
     Exception.Create( +  Assigned(HttpClientFactory) 
     Exception.Create(DLLName + 
   LibHandle <> INVALID_HANDLE_VALUE = 
==

.


2.DLL中輸出接口對象的生命周期管理

Delphi對接口采用引用計數的方法管理對象生命周期,但是DLL中輸出的對象可能不是被Delphi調用,其引用計數不一定正確,因此DLL中接口對象的生命周期不由Delphi編譯器自動生成的代碼管理,而是程序員自己控制,所以上面

的工廠包括構造和解析兩個接口對象的生命周期管理方法。

所有接口對象應該集成自下面的接口,而不應該繼承自Delphi自帶的TInterfacedObject:

  TIntObject = 
     QueryInterface( IID: TGUID;  Obj): HResult;  _AddRef: Integer;  _Release: Integer;  TIntObject.QueryInterface( IID: TGUID; 
   GetInterface(IID, Obj) = 
  == -= -
;


3.自管理接口對象在Delphi調用注意事項

1)接口賦值

  錯誤代碼:(Delphi編譯器產生代碼會先判斷接口指針是否為nil,如果非nil自動調用接口的_Release方法)

  =, ,, 

  建議代碼:

  ):==FServer.Param;  //

2)局部接口變量
  錯誤代碼:

  =TTcpConnectionServerEventAdapter.Create(Self =TTcpConnectionEventAdapter.Create(Self =TConnectionEventAdapter.Create(Self =, ,, =;

上面代碼中運行退出後,Delphi編譯器會在此代碼後面自動調用P1._Release; P2._Release,
  建議代碼:

  =TTcpConnectionServerEventAdapter.Create(Self =TTcpConnectionEventAdapter.Create(Self =TConnectionEventAdapter.Create(Self =, ,, =

;

 

3)函數返回值為接口指針

如下面的示例中FServer.Param定義為function THttpServer.Param:IHttpServerParam,返回的是接口類型,下面的代碼直接調用Param.SetValue方法:

  =TTcpConnectionServerEventAdapter.Create(Self =TTcpConnectionEventAdapter.Create(Self =TConnectionEventAdapter.Create(Self   RegistObserver(FServer, FServerEvent);
  TcpClientFactory.CreateTcpConnection(FRemote);
   RegistObserver(FRemote,FTcpConnectionEvent);
;

 上面的代碼,Delphi編譯器會自動生成兩個接口變量,保存FServer.Param和FRemote.Param,由於FServer和FRemote為TTcpServerSplitter對象的全局變量,所以接口在TTcpServerSplitter對象釋放時,被調用_Release

將導致內存訪問異常。

  =TTcpConnectionServerEventAdapter.Create(Self =TTcpConnectionEventAdapter.Create(Self =TConnectionEventAdapter.Create(Self   RegistObserver(FServer, FServerEvent);
  TcpClientFactory.CreateTcpConnection(FRemote);
    RegistObserver(FRemote,FTcpConnectionEvent);
     Pointer(P2):=nil; end;

4)對象中的接口變量,在對象釋放時,需要將接口變量清空。

;

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved