解析Delphi中的LoadLibrary,GetProcAddress,FreeLibrary


GetProcAddress(Hinstance,lpname)用來獲取指定的動態連接庫函數的地址
Hinstance為由LoadLibrary返回的模塊句柄,lpname為文件名/函數名,返回值,成功返回動態連接庫的地址,失敗返回NULL,
FreeLibrary(Hinstance),Hinstance為由LoadLibrary返回的模塊句柄,功能是:釋放動態連接庫!
動態引入方式就是使用Windows的兩個API即LoadLibrary和GetProcAddress,前者用於獲得DLL的句柄,后者用於獲得DLL 中例程的地址,這種方式之所以被稱為動態的,是因為它不需要在程序的開始處把要引入的例程全部列出,只要在調用前引入,並且LoadLibrary可以指定不同的DLL,GetProcAddress可以指定不同的例程,最重要的是如果指定的DLL出錯,最多是API調用失敗,但不會導致程序終止,因此我們應該在程序中監視DLL的返回值,根據返回值作出相應的處理。程序示例如下: 
Var LibHandel:Thandlel;
LibHandle:=LoadLibrary(Pchar(DLLname));
以上首先聲明一個DLL的句柄,然后用LoadLibrary獲得DLL的句柄,其中DLLName是DLL的文件名,由於LoadLibrary是Windows的API,因此調用時要強制轉換成Pchar類型。
Var Getcount:Function(Index:integer):Integer;StdCall;
@Getcount:=GetProcAddress(LibHandle,’’GetCount’’); //很難明白,為什么前面要加@符號?
以上聲明了一個例程指針,指向一個函數,有一個Integer類型的參數,返回類型也是Integer,調用約定是StdCall方式,然后用GetProcAddress獲得DLL中GetCount例程的地址。
Var MyCount:Integer; 
MyCount:=GetCount(1);
以上是調用DLL中例程GetCount的例子。
DLL只能輸出例程,雖然DLL中也含有變量(全局變量),但程序不能直接引入這些變量,只能通過接口例程間接地訪問這些變量。DLL也不能直接訪問調用DLL的程序中的變量。
注意,不管那種方式,在編譯期,編譯器不檢查DLL是否存在以及要引入的例程是否存在等問題,因此這類錯誤在編譯期是檢查不出來的。
進程調用 LoadLibrary(或 AfxLoadLibrary)以顯式鏈接到 DLL。如果成功,函數將指定的 DLL 映射到調用進程的地址空間中並返回此 DLL 的句柄,該句柄可與用於顯式鏈接的其他函數(如 GetProcAddress 和 FreeLibrary)一起使用。
LoadLibrary
LoadLibrary 嘗試使用用於隱式鏈接的同一搜索序列來定位 DLL。如果系統無法找到 DLL 或者入口點函數返回 FALSE,LoadLibrary 將返回 NULL。如果對 LoadLibrary 的調用所指定的 DLL 模塊已映射到調用進程的地址空間中,則函數僅返回 DLL 的句柄並遞增模塊的引用數。
如果 DLL 有入口點函數,則操作系統在調用 LoadLibrary 的進程上下文中調用此函數。如果由於以前調用了 LoadLibrary 但沒有相應地調用 FreeLibrary 函數而導致 DLL 已經附加到進程,則不會調用此入口點函數。
加載擴展 DLL 的 MFC 應用程序應使用 AfxLoadLibrary 而不是 LoadLibrary。AfxLoadLibrary 在調用 LoadLibrary 之前處理線程同步。AfxLoadLibrary 的接口(函數原型)與 LoadLibrary 相同。
如果出於某種原因 Windows 無法加載 DLL,進程可以嘗試從錯誤恢復。例如,進程可通知用戶所發生的錯誤,並讓用戶指定 DLL 的其他路徑。
安全說明 如果代碼將在 Windows NT 4 或 Windows 2000 上運行,請務必要指定任何 DLL 的完整路徑名。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM