關於Windows平台下應用程序加載DLL模塊的問題.


本文將討論以下問題:

(1)Windows可執行程序會從哪些目錄下加載DLL.

(2)如何將可執行使用的DLL放置到統一的目錄下,而不是與EXE同一目錄.

(3)可執行程序加載了不該加載的DLL.

(4)Win7,Win8下,"\Windows\System32"中的可執行程序無法加載DLL.

 

(1)

當啟動一個可執行程序時,如果該程序需要加載其他DLL,那么當DLL的路徑不是完整路徑時,會先從當前目錄下查找,找不到會再搜索系統目錄,還是找不到的話,則依次搜索環境變量path的目錄.這個順序很重要.

我自己系統的默認環境變量path的目錄如下:

C:\Program Files (x86)\Microsoft DirectX SDK (June 2007)\Utilities\Bin\x86;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\TortoiseSVN\bin;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;c:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn\;;C:\Program Files (x86)\Microsoft Visual Studio 9.0\;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin

 

(2)

為了發布的軟件目錄清晰,我通常會將應用程序使用到的DLL放到一個統一的目錄下,方法就是設置path環境變量.

在VC環境下可以通過以下代碼設置path環境變量:

 1     // 設置Path環境變量
 2     char szOldPathBuffer[4096] = { 0 };  3     char szCurrPath[256] = { 0 };  4     char szNewPathBuffer[4096] = { 0 };  5     ::GetEnvironmentVariable("Path", szOldPathBuffer, sizeof(szOldPathBuffer));  6     ::GetCurrentDirectory(sizeof(szCurrPath), szCurrPath);  7  ::sprintf(szNewPathBuffer,  8         "%s\\ExternDll;%s",  9  szCurrPath, szOldPathBuffer); 10 
11     if(!::SetEnvironmentVariable("Path", szNewPathBuffer)) 12  { 13         ::MessageBox(NULL, szNewPathBuffer, "ERROR: Set Environment Failed!", 0); 14     }

 

(3)

這樣做可能會碰到問題,就是應用程序加載了不該加載的DLL.

舉個例子,應用程序中需要使用一個DLL為"physxcore.dll",將這個DLL放到某個path環境變量目錄中.而用戶的系統目錄下恰好也存在一個physxcore.dll.如果兩個physxcore.dll版本不一致,那么你的應用程序很可能無法啟動,或者出現莫名其妙的問題.這是我親身經歷的問題,當時覺得很奇怪,若干台同樣配置的機器,怎么就偏偏有一台不能運行呢?不知道這台機器裝了什么軟件,該軟件將這個physxcore.dll放置到了系統目錄下.解決辦法就是將physxcore.dll放到與EXE文件同目錄下.

 

(4)

我做過測試,如果將應用程序放到WIN7,WIN8的"\Windows\System32"目錄下,它將不法加載任何DLL,無論是顯示加載還是隱式加載.這個問題困擾了我很久,因為我寫過幾個屏保程序,這些程序在XP下設置屏保很正常,但Win7,Win8下就是無法運行.至今我也沒有找到什么合理的解釋.但可以將應用程序放到"\Windows\syswow64"或"\Windows\syswow32",程序放到這個目錄下,也能夠以屏保的方式運行.

 


免責聲明!

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



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