2016-04-20 40 views
-1

我有一個VisualStudio單元測試項目 - Tests.exe。此exe文件取決於dll項目AB,它們分別產生A.dllB.dll在win32加載器之前執行代碼?

當我執行Tests.exe它無法運行,因爲AB未被複制到exe的輸出目錄。我想避免這樣做,因爲有100個exes和dll。

相反,我想一些方法,以便調用SetDllDirectory API添加了AB DLL生活

所以TL目錄Windows加載程序之前執行代碼; DR - 如果一個EXE是缺少一個DLL,我怎麼能在「N.dll缺失」錯誤之前執行SetDllDirectory

+0

將可執行文件放在同一個文件夾中,讓生活更輕鬆 –

+0

Dll也需要在那裏,這是一個巨大的2000多個項目/許多解決方案等。我真的不能那樣做 – paulm

+1

是的,你可以。如果你不這樣做,那麼你需要運行時鏈接。 –

回答

0

使用延遲加載。從技術上講,這並不能回答你的問題 - 只有在加載了你的可執行文件導入的所有DLL之後,Win32加載器纔會調用你的入口點。但通過延遲加載,編譯器會發出執行即時調用的LoadLibraryGetProcAddress調用。您甚至可以自定義LoadLibrary調用,並以任何您喜歡的方式獲取DLL HMODULE

0

[i]如果exe文件丟失了dll文件,我怎麼才能在「N.dll丟失」錯誤之前執行SetDllDirectory

基本上你不能。該加載器代碼在任何用戶代碼之前執行,這些都是您可以嘗試強制加入該代碼段的限制。您可以在庫部分中將初始化代碼「向上」推送,但它仍然不允許您控制dll從哪裏加載。

那麼如何解決呢?

最簡單的方法是確保在執行測試之前將dll和/或exe構建到(或複製到)所需的位置。

構建解決方案;

  • VS允許您標記相關的項目,然後將dll複製到輸出文件夾 - 您可以這樣做。此外,如果項目是單個解決方案的一部分,請爲每個配置設置一個公共生成輸出文件夾。
  • 如果未將解決方案配置爲包含所有項目,則可以添加「預生成」步驟以將所需的依賴項複製到輸出文件夾,或者「生成後」以將exe複製到某個位置包含執行測試exe之前的所有依賴關係。或者,構建到一個公共文件夾;按慣例或環境變量定義。

運行時解決方案;

  • Delay load the dll路徑被修復後。對於每個dll延遲加載,請將/delayload switch添加到命令行;

    /DELAYLOAD:A.dll 
    
  • 您也可以直接使用功能,如LoadLibraryGetProcAddress控制的DLL的加載,直到後來,你就必須比他們從以及加載的位置控制。這可能需要某種「存根」來將dll函數作爲C兼容函數公開,因此它可能遠非理想,但它是可能的。

+0

這個怎麼樣:https://msdn.microsoft.com/en-us/library/yx1x886y.aspx好像延遲加載可能會破壞事情? – paulm

+0

是的,您需要確保您知道並根據這些限制進行編碼。 – Niall

0

Visual Studio對C++項目做的不好的事情之一是產生「runnable」輸出。

我發現處理這個最簡單的方法是設置一個解決方案級別的輸出文件夾,所有的二進制文件都被構建到。這確保了所有的EXE和DLL都在同一個地方,並且他們需要的任何其他資源都可以部署到同一個文件夾中。

tl; dr - 不是將dll複製到單元測試exe的文件夾 - 而是將單元測試的輸出路徑設置爲dll的文件夾。

相關問題