程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 第十章-動態鏈接庫編程(一)(4)

第十章-動態鏈接庫編程(一)(4)

編輯:Delphi

10.3 利用DLLs實現數據傳輸 

10.3.1 DLLs中的全局內存 

Windows規定:DLLs並不擁有它打開的任何文件或它分配的任何全局內存塊。這些對象由直接或間接調用DLLs的應用程序擁有。這樣,當應用程序中止時,它擁有的打開的文件自動關閉,它擁有的全局內存塊自動釋放。這就意味著保存在DLLs全局變量中的文件和全局內存塊變量在DLLs沒有被通知的情況下就變為非法。這將給其它使用該DLLs的應用程序造成困難。

為了避免出現這種情況,文件和全局內存塊句柄不應作為DLLs的全局變量,而是作為DLLs中過程或函數的參數傳遞給DLLs使用。調用DLLs的應用程序應該負責對它們的維護。

但在特定情況下,DLLs也可以擁有自己的全局內存塊。這些內存塊必須用gmem_DDEShare屬性進行分配。這樣的內存塊直到被DLLs顯示釋放或DLLs退出時都保持有效。

由DLLs管理的全局內存塊是應用程序間進行數據傳輸的又一途徑,下面我們將專門討論這一問題。 

10.3.2 利用DLLs實現應用程序間的數據傳輸 

利用DLLs實現應用程序間的數據傳輸的步驟為:

1. 編寫一個DLLs程序,其中擁有一個用gmem_DDEShare屬性分配的全局內存塊;

2. 服務器程序調用DLLs,向全局內存塊寫入數據;

3. 客戶程序調用DLLs,從全局內存塊讀取數據。 

10.3.2.1 用於實現數據傳輸的DLLs的編寫 

用於實現數據傳輸的DLLs與一般DLLs的編寫基本相同,其中特別的地方是:

1. 定義一個全局變量句柄: 

var

hMem: THandle;

2. 定義一個過程,返回該全局變量的句柄。該過程要包含在exports子句中。如: 

function GetGlobalMem: THandle; export;

begin

Result := hMem;

end;

3. 在初始化代碼中分配全局內存塊:

程序清單如下: 

begin

hMem := GlobalAlloc(gmem_MOVEABLE and gmem_DDEShare,num);

if hMem = 0 then

MessageDlg('Could not allocate memory',mtWarning,[mbOK],0);

end.

num是一個預定義的常數。

Windows API函數GlobalAlloc用於從全局內存堆中分配一塊內存,並返回該內存塊的句柄。該函數包括兩個參數,第一個參數用於設置內存塊的分配標志。可以使用的分配標志如下表所示。

表10.3 全局內存塊的分配標志

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

標 志 意 義

—————————————————————————————————

gmem_DDEShare 分配可由應用程序共享的內存

gmem_Discardable 分配可拋棄的內存(只與gmem_Moveable連用)

gmem_Fixed 分配固定內存

gmem_Moveable 分配可移動的內存

gmem_Nocompact 該全局堆中的內存不能被壓縮或拋棄

gmem_Nodiscard 該全局堆中的內存不能被拋棄

gmem_NOT_Banked 分配不能被分段的內存

gmem_Notify 通知功能。當該內存被拋棄時調用GlobalNotify函數

gmem_Zeroinit 將所分配內存塊的內容初始化為零

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

有兩個預定義的常用組合是:

GHND = gmem_Moveable and gmem_Zeroinit

GPTK = gmem_Fixed and gmem_Zeroinit

第二個參數用於設置欲分配的字節數。分配的字節數必須是32的倍數,因而實際分配的字節數可能比所設置的要大。

由於用gmem_DDEShare分配的內存在分配內存的模塊終止時自動拋棄,因而不必調用GlobalFree顯式釋放內存。

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