為什麼DLL在導入項沒有成功解析時會加載失敗?

漫漫開發路 發佈 2020-04-26T19:45:07+00:00

到了Win32時代,開發團隊覺得這是一個很糟糕的設計,因為有時候人們會將一個為Windows3.1開發的應用程式拷貝到Windows 3.0上並運行,一開始,這個應用程式運行的還不錯,但是如果這個應用調用了一個只在Windows 3.1平台上可用的函數時,應用程式會立即崩潰。

短答案

因為我們測試過其他方案,只有這種方式是最好的。

長答案

在16位的Windows系統上,如果一個模塊沒有滿足其所有的導入表,則它仍然可以被系統加載。只要你不調用一個丟失的導入項,則一切都還是正常的。如果你嘗試調用一個丟失的導入項,程序將會立即崩潰並顯示」不可恢復的錯誤」的對話框提示。

到了Win32時代,開發團隊覺得這是一個很糟糕的設計,因為有時候人們會將一個為Windows 3.1開發的應用程式拷貝到Windows 3.0上並運行,一開始,這個應用程式運行的還不錯,但是如果這個應用調用了一個只在Windows 3.1平台上可用的函數時(例如,GetSaveFileName這個函數),應用程式會立即崩潰。

因此Win32開發團隊決定,如果有任何一個導入項沒有被成功解析,則應用程式一開始加載的時候就會失敗。如果上面例子中的應用程式開發商希望能將他們的應用運行在Windows 3.0上,則可以通過顯式地使用GetProcAddress來表明這一點。因為如果必須顯式調用GetProcAddress,則可能需要檢查返回值。

當人們大聲疾呼時,有時會出現此問題:」天哪,我應該有一種方法可以將導入項標記為』可選』-如果無法綁定,則加載應該不會失敗。在調用綁定之前,應用程式有責任驗證綁定是否成功。」,這些人可能是無意中在要求歷史的重演,因為這又會回到我們一開始碰到問題的地方。

總結

如果對一個函數調用在當前平台上是否可用存在疑慮,可以嘗試先用GetProcAddress來獲取函數地址,如果函數不可用則進行相應的提示或者錯誤處理,儘量地讓你的應用優雅的退出。


關鍵字: