程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 利用DelayLoad來優化應用程序的性能及攔截API

利用DelayLoad來優化應用程序的性能及攔截API

編輯:vc教程

在 1998年12月的MSJ出版刊物中, Jeffrey和我寫了關於 在 vc6中使用DelayLoad 功能的專欄.最終結果,是證明了它是多麼cool.但是,不幸的是,還有很多人不了解DelayLoad,他們以為這個新特點是 最新版本的WINNT才有的.

在開始的時候,讓我重申一遍:DelayLoad不是最新的操作系統帶的特有功能,它可以在任何win32系統中起作用.我將寫一個簡單例子來說明. DelayLoadProfile, 實現了一個很小功能,很多程序都可以得益於它.

預覽:

通常的,當調用一個dll中的函數時,連接器會將dll和函數加入你的可執行文件.最後,所有引用的函數會放在imports段中. 當加載該程序的時候,win32程序加載器會掃描所有imports段的每個dll.加載,和重新定位imports段的所有函數,將信息寫入 引入地址表(ImportAddress Table, IAT).簡單說來,IAT就是一個函數指針的表.調用該 引入函數的時候,就到IAT中去找. 那麼,DelayLoad的機理是什麼呢?當你為一個Dll進行"DelayLoad"的時候,連接器不將原來的值放入imports段,相反,它為每個DelayLoad的引入函數的名稱和地址,生成一個小的根區, 備份下來。第一次引用的時候,它調用LoadLibrary加載Dll,然後,它調用GetProcAddress取得該函數的地址。最後,改寫自己在IAT的值,以便以後的程序可以直接調用.

上面的是簡化的步驟.實際上,根區是一小段代碼,它以靜態的方式連接到可執行文件中.代碼在delayimp.lib中,必須被 連接程序引用.並且,該代碼要足夠智能,當一個函數第一次被引用的時候,要調用LoadLibrary,以後調用就不用引用了. 和引用Dll相比,DelayLoad不會加太多的時間和空間,這種方式 調用LoadLibrary只會引起稍微一點點的性能損失.每次程序啟動,在針對引入表的函數地址定位的時候,依次對DelayLoad引入的調用GetProcAddress,相對於Win32加載器來說,所損失的性能也可以忽略不記.

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