解決某些 C++ 程式在 VC2005 debug 模式下找不到 MSVCR80.DLL 的問題


恩…自己寫完後,都覺得真是超長的一個標題。首先呢,這個問題的發生,主要是因為 Heresy 這邊工作上目前都是用 Visual Studio 2005 來寫 C++ 的程式;而為了簡化開發呢,在不少非核心的部分(例如讀取影像檔案),有使用一些現有的 Open Source 函式庫。而這次碰到的問題,就是在使用 libgeotiff 時發生的了…

主要狀況,就如同標題所述,只要執行某些 debug 版的程式,就會出現找不到 MSVCR80.DLL 的問題(如下圖對話框);而相對的,release 版則沒有任何問題。

image

MSVCR80.dll 基本上是微軟的 C Runtime Library 的一個檔案,在執行 Visual C++ 2005 (8.0) 所編譯的程式時,大多需要這個檔案;對於一般使用者來說,只要有安裝對應的「可轉發套件」(例如:Microsoft Visual C++ 2005 SP1 可轉散發套件),大多就會把檔案複製到系統裡了~而實際上,目前有不少程式都會先自動裝上這東西。

而理論上,在有安裝 Visual Stuio 的電腦上,不應該會出現這樣的問題?本來一直以為是 Windows 或 Visual Studio 的設定爛掉了,後來找了老半天,才發現其他程式似乎沒有類似的問題;後來再進一步釐清,似乎和設定無關,而是其他方面的問題。到目前為止,Heresy 是認定這應該是「部分有使用到 release 版 libgeotiff 的程式」才有的問題;而類似的問題(不見得是 libgeotiff),其實在網路上也是找的到討論的。

發生的原因呢?似乎是因為 debug 版的程式,用了 release 版的動態函式庫,導至在某些其況下,會沒有辦法正確地讀取 release 版的 MSVCR80 所造成的(話說,libtiff 就不會有這問題?)。

最根本的解決方法,應該就是把所有函式庫,都各自建置 release、debug 兩種版本了~但是其實這樣滿麻煩的,不但在一般情況下,不太可能會進去追函式庫裡的程式;而且如果是像 Heresy 這邊還有 win32 和 x64 的話…就變成要維護四種版本了… orz

後來有找到兩種可能的解法,其實意義是一樣的;就是要把相依性(dependency)的資訊,強制加到程式的執行檔裡。而所需的相依性資訊的來源,其實就是 VC 2005 在編譯後會產生的 manifest 檔(中文版把這個叫做「資訊清單檔」)了~

解法一:在程式的原始碼內加入相依性資訊。

在程式的 .CPP 檔裡,加上

#pragma comment(linker, ""/manifestdependency:type='Win32' name='Microsoft.VC80.CRT' version='8.0.50727.4053' processorArchitecture='X86' publicKeyToken='1fc8b3b9a1e18e3b' language='*'"")

後,再重新編譯,應該就可以在執行時強制去讀取正確的 dll 檔。

不過,內部的資訊,可能需要根據編譯函式庫時所產生的 manifest 檔(例如 Heresy 這邊是 geotiff.dll.manifest)做對應的修改;像在 x64 時,processorArchitecture 就要從 X86 改成 amd64。

所以這樣的方法,第一個麻煩是要修改原始碼;而且像同時有 win32 和 x64  的設定的話,就還必須要用 ifdef 的方法來處理,算是滿麻煩的…

 

解法二:在專案設定裡,設定要額外加上 manifest 檔。

由於解法一滿麻煩的,所以 Heresy 後來是透過專案的設定來解決。這個方法的設定方法如下:

  1. 在專案上按右鍵,選「Properties(屬性)」
  2. 然後找到「Configuration Properties(組態屬性)」、「Manifest Tool(資訊清單工具)」裡的「Input and Output(輸入和輸出)」
  3. 在「Additional Manifest Files(其他資訊清單檔)」裡,把函式庫的 manifest 檔加進去就可以了~

image

而針對 win32 和 x64 這樣不同的平台,也只要設定加上不同的 Manifest 檔就好了~

現階段知道的解法只有這樣啦~可以的話,還是希望可以在編譯函式庫的時候,直接解決掉這問題,不用像現在這樣還要額外處理…不過也不知道能不能解就是了… ~_~

順帶一提,透過 mt 把 Manifest 的資訊加到函式庫的 DLL 檔裡似乎沒有用…


參考資料:

對「解決某些 C++ 程式在 VC2005 debug 模式下找不到 MSVCR80.DLL 的問題」的想法

  1. 恩…的確,這到沒想到。不過都已經全改完了,懶得再換方法了 XD不過,還是希望可以徹底解決啦…不知道到底是不是 libgeotiff 編譯參數的問題 orz

  2. 寫在某個檔, 只要include 就不用每次改了! 這樣應該比在project setting 方便

  3. to 周尚達這個問題安裝 Redistributable Package 並無法解決。因為實際上該檔案還是存在的,只是程式不會去 load 他…

  4. to KunI文內有提到了「同時有 win32 和 x64 的設定的話,就還必須要用 ifdef 的方法來處理,算是滿麻煩的…」Heresy 只是不想在原始碼裡改,所以才在專案設定裡改。

  5. Windows 程式的 processorArchitecture 應該有 _X86_, _AMD64_, _68K_, _MPPC_, _IA64_, _MAC 這些, 可以在windows.h 找到

  6. 1. 的方法不能用 #if defined(_X86_) 來解 processorArchitecture=’X86′ 的問題嗎?

  7. 是說我用的是VC2008 但是他找不到的是MSVCP90D.dll檔也可以比照辦理嗎?(舉手)

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.