8

我在Visual Studio 2010中有一個非託管的C++項目。它使用boost,glut和來自供應商的另一個庫。Visual Studio 2010中的動態和靜態鏈接和部署

我已經建立了項目來創建一個更「dll-indepenendent」的可執行文件。所有boost庫都是靜態鏈接的,並且在可執行文件所在的目錄中不需要dll。

同樣的事情爲Glut,我已經鏈接靜態glut32.lib而不是glut32.dll,並再次沒有問題。

我已經爲運行時庫選擇了NON-dll版本,即Multithreaded Debug(用於調試配置)和Multithreaded for Release配置。

現在,我以前說過的供應商提供了兩個替代品Vendor.lib和Vendor.dll。

Vendor.lib被添加到鏈接器 - >其他依賴項中,但是在運行時我總是必須將Vendor.dll放在可執行文件的同一目錄中,否則運行時環境會抱怨,因爲它沒有找到Vendor .dll庫。

我應該如何解決這個問題?我想避免在每個目錄中放入.dll文件。

我不想把dll放在exe文件的同一目錄中,一般來說,在Visual Studio中部署非託管C++控制檯應用程序的準則是什麼?

我知道有很多關於這個論點的問題和網頁,但沒有一個澄清我這一點。

有些想法?

回答

10

微軟在處理它的方式上有點有趣:當您創建 .dll時,還會創建一個.lib,其中包含 .dll中的公共符號。您必須鏈接到.lib才能加載運行時的 .dll,但該.lib仍不是靜態庫。如果您的供應商 提供靜態鏈接的版本,則不會有.dll或 兩個.lib(推測可能在不同的目錄中或具有不同的名稱)。 只是微軟進行嚴重開發的另一個例子,更難 比必要的困難。

+2

這不是MS特定的。 Linux也有導入庫。 – rubenvb 2012-03-05 14:18:46

+8

Unix有兩種類型的「庫」:庫(.a文件)和共享對象(.so文件)。提供庫(一般意義上)的供應商通常會提供這兩種庫。如果您使用.a文件進行鏈接,則可以靜態鏈接,如果使用.so鏈接,則可以動態鏈接。與Microsoft解決方案的問題是1)您有兩個不同的文件用於動態鏈接,並且2)其中一個文件具有與靜態庫相同的名稱。 – 2012-03-05 14:21:10

+0

謝謝你的回答。也許我不是唯一一個對這個話題感到困惑的人。所以,正如你所說,有兩種.lib文件,一種是在需要動態庫時創建的,另一種可以是靜態庫。我沒有找到另一個Vendor.lib文件,所以我想我是第一個案例...謝謝! – linello 2012-03-05 14:34:28

7

Vendor.lib需要是靜態編譯的庫。如果當你鏈接這個你仍然需要Vendor.dll,聽起來像Vendor.lib實際上是一個導入庫,而不是一個靜態庫。

檢查供應商是否提供了另一個Vendor.lib(應該比當前的.lib大一點),這是一個靜態庫並嘗試鏈接到該庫。如果是這樣,你將不需要該DLL。

+0

不幸的是,我沒有在該庫中的其他.lib文件,所以我想我在動態鏈接的情況下。 沒有其他方法可以包含.dll而不是將其複製到可執行目錄中(或將它們複製到System32文件夾中?) – linello 2012-03-05 14:35:54

+0

如果您有權訪問供應商源,則可以將vendor.lib自己編譯爲靜態庫。否則,如果你必須使用共享庫,那麼你的exe需要在運行時訪問它,這意味着使用exe將它添加到文件夾中,或者將它放在包含在%PATH%中的文件夾中(約定是System32文件夾)。 – Fraser 2012-03-05 14:49:49