簡體   English   中英

如何讓DLL在不同的Windows版本上運行?

[英]How to have a DLL work on different Windows versions?

我正在編譯自己的DLL,包含幾個.o文件。 其中一個.o文件具有調用僅在Windows 7上支持的SHLoadLibraryFromItem的函數。 除非使用DLL的應用程序在Windows 7上運行,否則永遠不會調用該函數。(是的,我確定。)

但是,在較舊版本的Windows(例如,XP)上運行應用程序時,整個應用程序在啟動時崩潰,並顯示錯誤“無法找到指定的過程”。 雖然錯誤沒有指定找不到哪個過程,但如果我注釋掉對SHLoadLibraryFromItem的調用,那么一切正常。

問題:

  1. 為什么Windows試圖找到SHLoadLibraryFromItem即使它沒有在XP上調用?
  2. 有沒有辦法讓Windows 這樣做,即只在運行Windows 7時找到SHLoadLibraryFromItem ,即某種懶惰綁定?
  3. 如果沒有,最好的方法是什么?

我能想到的唯一方法就是:

  1. 使用LoadLibrary加載SHLoadLibraryFromItem所在的Windows DLL並使用GetProcAddress手動獲取地址到指向函數的指針並使用指針調用SHLoadLibraryFromItem而不是?
  2. 有兩個DLL:一個包含Windows 7支持的功能,只有在Windows 7上運行時才會加載。

還有其他想法嗎? 我真的更喜歡上面提到的某種懶惰綁定。

更新

請仔細閱讀我實際操作的內容。 我在第一段中明確指出,除非我知道應用程序在WINDOWS 7上正在運行,否則不會調用SHLoadLibraryFromItem

應用程序僅在加載 DLL時崩潰。

鏈接器將模塊中的引用嵌入到所使用的每個API函數中。 當Windows加載程序加載可執行文件及其模塊時,它需要將代碼中的所有調用“掛鈎”到實際加載API函數的內存中的位置。 如果找不到它們,它將無法繼續。

使用LoadLibraryGetProcAddress是解決此問題的“標准”方法。

使用兩個DLL對您沒有幫助,因為只要其中一個無法加載您的應用程序仍然無法啟動。 您可以通過使用延遲加載來解決這個問題,將所有依賴於新O / S的代碼放在一個單獨的模塊中,並將所有對該模塊的調用包裝在Win32 SEH異常處理程序中(延遲加載時會出現SEH異常)無法加載模塊)。 優點是你可以使用“自動”鏈接而不需要亂七八糟的函數指針,但異常處理可能非常糟糕。

這篇文章解釋了一下,並給出了一些如何整齊地包裝它的例子。

為什么Windows試圖找到SHLoadLibraryFromItem,即使它沒有在XP上調用?

當應用程序加載到內存中時,Windows會解析引用,而不是在進行調用時。 這稱為“動態鏈接”(與鏈接器的靜態鏈接相反),但它不是真正動態的。 因此,它不知道是否在運行時調用特定方法。

暫無
暫無

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

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