msvcrt.lib 與 libcmt.lib 衝突的解決方式

有時候我們會遇見諸如 libcmt.lib/msvcrt.lib/msvcprt.lib 之間出現重覆定義的問題,這是因為程式間所連結進來,各個 library 之間的 CRT 版本不一致的關係。

在 MSVC++ 2005 中,Properties 中的 Code Generation 可以選擇 Runtime Library,共有四種選擇,它們會各自對應到四種 library:

Multi-threaded (/MT) - libcmt.lib
Multi-threaded Debug (/MTd) - libcmtd.lib
Multi-threaded DLL (/MD) - msvcrt.lib
Multi-threaded Debug DLL (/MDd) - msvcrtd.lib

等於說我們選了其中一項,MSVC 就會自動幫我們連結相對應的 CRT 版本(前提是有使用 C 的函式。不過,應該大家都會用吧?!)。至於 msvcprt.lib 與 msvcprtd.lib 則是對應到 Release 及 Debug 版本的 C++ Runtime Library(只要程式中有使用到 C++ function,MSVC 自動會連結進來)。

在程式中所連結進來的各個 library,其 Runtime Library 選項都得一致。假如我們在連結時出現以下錯誤:

1>Linking...
1>msvcprt.lib(MSVCP80.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in Check3G.lib(CheckApi.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library

上面的錯誤是說,程式要連結 msvcprt.lib 中時,發現同一個符號在 Check3G.lib 中已經定義過了(最後一行指明已經在 libcmt.lib 中定義過了)。這個例子原因是,Check3G.lib 使用 Multi-threaded (/MT) 選項,連結 libcmt.lib 進來;但程式本身使用 Multi-threaded DLL (/MD),連結 msvcprt.lib 進來。如此當然會有衝突囉!

解決方式就是將 Check3G.lib 重新編譯,使用 Multi-threaded DLL (/MD) 選項,就可以解決了。那如果 Check3G.lib 是 3rd party 提供,我們沒原始碼呢?解決方式就是使用 MSVC 中的 Ignore Specific Library(Linker/Input 選項),將衝突的 library 給 ignore 掉就可以啦!

底下是使用 dumpbin 查看程式 dependency 的結果。先列出來的是使用 Multi-threaded (/MT) 的方式,CRT 是直接 static 連結進程式,故在 dependency 中看不到相對應的 dll。

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    AsDiag.dll
    QtCore4.dll
    QtGui4.dll
    AsMultiTouch.dll
    POWRPROF.dll
    KERNEL32.dll
    USER32.dll
    ADVAPI32.dll
    SHELL32.dll
    ole32.dll
    OLEAUT32.dll
    QMSL_MSVC6R.dll

  Summary

        C000 .data
       3C000 .rdata
       33000 .text

而下面是使用 Multi-threaded DLL (/MD) 的結果。可以看出 MSVCP80.dll/MSVCR80.dll 這兩個 dll 變成程式的 dependency。

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    AsDiag.dll
    QtCore4.dll
    QtGui4.dll
    AsMultiTouch.dll
    POWRPROF.dll
    KERNEL32.dll
    USER32.dll
    ADVAPI32.dll
    SHELL32.dll
    ole32.dll
    OLEAUT32.dll
    MSVCP80.dll
    MSVCR80.dll
    QMSL_MSVC6R.dll

留言

熱門文章