簡體   English   中英

Delphi:使用LoadLibrary加載DLL的奇怪行為

[英]Delphi: Odd behaviour loading DLLs with LoadLibrary

我正在用Delphi構建一個插件系統(其中一些人一直在幫助我完成這項任務)。

要搜索DLL文件,我使用了TSearchRec,它在exe路徑中搜索dll文件,然后使用LoadLibrary訪問它們。 然后,如果公開了某個功能(使用GetProcAddress),則將其作為插件加載。 如果不是,則執行FreeLibrary,然后繼續下一個文件。

在測試過程中,我注意到當TSearchRec找到恰好在該路徑中的“ borlndmm.dll”時,它會加載並搜索我的插件函數,當然找不到,但是如果執行FreeLibrary,我會得到訪問沖突。

同一路徑中的其他無插件dll(如libmariadb.dll)可以安全地釋放而不會出錯。

當然,通過將我的插件dll放在自己的路徑中,而沒有任何其他dll文件,可以輕松解決此問題,即使出於性能原因,這也會更好,因為它不必加載任何不該加載的庫。

但我想了解為什么會這樣。 有任何想法嗎?

謝謝Nuno Picado

為什么你碰到一些DLL時出現問題的原因是因為在調用LoadLibrary它加載DLL執行代碼-具體而言,DLL的初始化代碼。 在Delphi項目中,這包括單元初始化部分。 如果是borlandmm.dll,則dll初始化代碼會將其自身插入到主機exe進程的運行時庫中,用DLL中的內存管理器替換默認的內存管理器。 這並不是可逆的操作-不能在DLL關閉代碼中刪除自身(部分原因是不能保證在所有情況下都可以執行DLL關閉代碼)。

因此,請小心使用LoadLibrary,因為在您甚至不知道DLL是什么之前,您基本上是在執行任意代碼。 如果您真的必須窺視大量來歷不明的任意DLL,一種比較安全的方法是將DLL作為資源映像而不是可執行映像加載。 這會將文件加載到內存中,但不執行DLL初始化代碼。 請參見LoadLibraryEx()和LOAD_LIBRARY_AS_IMAGE_RESOURCE標志。

正如您在前面的評論中提到的,可以做很多事情來減少需要加載的DLL的數量,使其完全符合用戶/管理員希望您的應用程序要加載的DLL,而不是加載您可以找到的所有東西。

  1. 要求DLL文件名具有自定義擴展名或文件名模式。 (例如,插件* .mod)
  2. 僅從特殊的子目錄加載DLL。 這在目錄級別的訪問控制中效果很好,因為在大多數系統上,bin目錄都不是普通用戶可寫的。 有人必須具有管理員權限才能將DLL放入特殊子目錄中。
  3. 僅加載在用戶定義的配置文件中命名的DLL文件。
  4. 以上任意組合

該DLL實現了共享內存管理器。 它被設計為僅與加載時間鏈接一起使用。 它由加載程序加載,直到進程結束才卸載。 一旦加載,它將承擔所有將來在進程中進行的堆分配和釋放的責任。 因此,它改變了主機進程的行為。 無法動態加載。

故事的寓意是不要將隨機DLL加載到您的進程中。 僅加載您或您的程序用戶明確要求加載的DLL。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM