国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Windows的動態鏈接庫原理及使用2

2019-11-17 05:37:04
字體:
來源:轉載
供稿:網友

  3  利用DLLs實現數據傳輸

3.1 DLLs中的全局內存

  Windows規定:DLLs并不擁有它打開的任何文件或它分配的任何全局內存塊。這些對象由直接或間接調用DLLs的應用程序擁有。這樣,當應用程序中止時,它擁有的打開的文件自動關閉,它擁有的全局內存塊自動釋放。這就意味著保存在DLLs全局變量中的文件和全局內存塊變量在DLLs
沒有被通知的情況下就變為非法。這將給其它使用該DLLs的應用程序造成困難。
  為了避免出現這種情況,文件和全局內存塊句柄不應作為DLLs的全局變量,而是作為DLLs中過程或函數的參數傳遞給DLLs使用。調用DLLs的應用程序應該負責對它們的維護。
  但在特定情況下,DLLs也可以擁有自己的全局內存塊。這些內存塊必須用gmem_DDEShare屬性進行分配。這樣的內存塊直到被DLLs顯示釋放或DLLs退出時都保持有效。
  由DLLs治理的全局內存塊是應用程序間進行數據傳輸的又一途徑,下面我們將專門討論這一問題。

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

  利用DLLs實現應用程序間的數據傳輸的步驟為:
  1. 編寫一個DLLs程序,其中擁有一個用gmem_DDEShare屬性分配的全局內存塊;
  2. 服務器程序調用DLLs,向全局內存塊寫入數據;
  3. 客戶程序調用DLLs,從全局內存塊讀取數據。

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用于從全局內存堆中分配一塊內存,并返回該內存塊的句柄。該函數包括兩個參數,第一個參數用于設置內存塊的分配標志。可以使用的分配標志如下表所示。
                        表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顯式釋放內存。

3.2.2        服務器程序的編寫

  服務器程序必須包含對DLL的調用代碼,如:

        function GetGlobalMem: THandle; far; external 'c:/dlls/glbmem';

  通過調用該函數,服務器可以獲得全局內存塊的句柄。
  在寫入數據前,服務器必須鎖定全局內存,以避免在寫入過程中Windows移動該內存塊的位置。
  函數GlobalLock鎖定全局內存并返回指向該內存塊的指針:

        pMem := GlobalLock(hMem);

  對pMem的任何修改都會反映到全局內存塊中。
  對內存塊進行操作后,調用GlobalUnLock進行解鎖。內存塊操作之后盡早解鎖,有利于Windows充分利用內存資源。
  服務器寫入數據的實現代碼如下。

        var
          hMem: THandle;
          pMem: PChar;
        begin

          hMem := GetGlobalMem;             {獲得全局內存塊的句柄}
          if hMem <> 0 then
          begin
            pMem := GlobalLock(hMem);    {加鎖全局內存塊}
            if pMem <> nil then
            begin
              StrPCopy(pMem,Memo1.text);  {向全局內存塊寫入數據}
              GlobalUnlock(hMem);         {解鎖全局內存塊}  
            end
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 盘锦市| 陵川县| 历史| 营口市| 海原县| 祥云县| 曲沃县| 阿拉尔市| 彭山县| 萍乡市| 巴东县| 临沧市| 金塔县| 泽库县| 南溪县| 漳平市| 获嘉县| 云龙县| 蕲春县| 高碑店市| 边坝县| 昌乐县| 若尔盖县| 广昌县| 青田县| 水富县| 静海县| 浦城县| 沁阳市| 漳州市| 军事| 环江| 天峻县| 宁强县| 共和县| 平定县| 金华市| 聂拉木县| 龙岩市| 许昌市| 岢岚县|