簡體   English   中英

使用運行時DLL(/ MD)避免DLL與運行時相關

[英]Avoid runtime dependency with a dll using runtime DLL (/MD)

我們使用VS2012,並具有依賴於運行時DLL(/ MD)的dll。 該dll用於許多不同的項目,並且不能輕易更改。

我們還有一個小的啟動器可執行文件,該可執行文件必須能夠在全新安裝的系統上運行,因此沒有安裝運行時。 它與運行時(/ MT)靜態鏈接。

現在,此exe取決於上述dll。

照原樣,該exe文件未構建[1]。 我觀察到,通過忽略MSVCRT(/NODEFAULTLIB:"MSVCRT.lib“)來構建它可以解決[1],但會產生[2]。 在“強制符號引用”中添加報告為錯誤的少量符號(例如/ INCLUDE:“ _ strncpy”),使構建成功。

但是,使用Dependency Walker檢查生成的exe會顯示通過我們的dll對運行時DLL的依賴性[3]。 我確認其中存在字符串[3]。 嘗試在Vista的全新安裝上運行exe失敗(錯誤說[3]中的DLL丟失)。 我擔心這是不可能的,而且我還沒有發現任何暗示它的信息。

靜態鏈接的exe可以為動態鏈接的dll提供運行時功能嗎? 如果是,怎么辦?

謝謝

參考文獻:

  1. 1> MSVCRT.lib(MSVCR110.dll):錯誤LNK2005:_sprintf已在libcmt.lib(sprintf.obj)中定義
  2. 錯誤LNK2001:無法解析的外部符號__imp__strncpy
  3. MSVCP110.dll,MSVCR110.dll

是的,靜態鏈接的exe可以為DLL提供功能。 但是,使用標准庫函數進行操作比其價值更大。

您需要使用/NODEFAULTLIB停止使用其自己的運行時副本來構建DLL。 這將使您產生大量鏈接錯誤,因為DLL使用的標准庫的每個部分以及某些供應商擴展現在都無法解決。

其中的每一個都需要使用模塊定義文件添加到EXE導出表中。 EXE鏈接期間將生成導入庫。 然后將該導入庫提供給DLL,以滿足其外部需求,從而解決它們。

最后,您將只有一個運行時庫副本,從而允許您的EXE和DLL共享庫對象,例如FILE*和堆(因此您可以在其中分配一個,而在另一個分配中免費)。 但是DLL和EXE將非常緊密地耦合在一起。 對DLL的幾乎任何更改都可能破壞構建,並要求EXE進行新的導出以對其進行修復。 您絕對不能將對DLL的更新與對EXE的更新分開提供。

一種更簡單的方法(仍使DLL大小減小)將是使用延遲加載。 這樣,盡管在沒有先安裝運行時可再發行文件的情況下仍然無法加載DLL,但是在進程啟動期間不會發生故障,並且EXE將有機會檢查運行時的存在並安裝可再發行文件。 或診斷並處理DLL加載失敗。

在極端情況下,EXE可以完全避免使用標准庫,確保可再發行組件的存在,然后為所有需要標准庫運行時的復雜邏輯調用延遲加載DLL。

在后一種情況下,由於EXE沒有使用運行時的DLL版本,因此您無法在EXE和DLL之間共享標准庫對象。 但是耦合要寬松得多。 我認為這是值得權衡的。

最終,我們將dll構建設置更改為/ MT。 我不知道有什么其他方法可以解決問題。

如果您的.exe需要在干凈的操作系統上運行,則它不能依賴於動態鏈接的任何DLL,因為如果沒有運行時DLL,這些DLL(以及.exe)就無法加載。 您是否考慮過本地應用程序部署 然后,.exe和dll都可以使用/ MD構建。

可以創建一個可以作為DLL或靜態庫構建的項目。 小型啟動程序可執行文件應與DLL項目的靜態庫配置鏈接。

暫無
暫無

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

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