默認庫“LIBCMTD”與其他庫的使用衝突;請使用 /NODEFAULTLIB:library
You are trying to link with incompatible libraries. Important The run-time libraries now contain directives to prevent mixing different types. You’ll receive this warning if you try to use different types or debug and non-debug versions of the run-time library in the same program. For example, if you compiled one file to use one kind of run-time library and another file to use another kind (for example, single-threaded versus multithreaded) and tried to link them, you’ll get this warning. You should compile all source files to use the same run-time library.
總之,一句話,lib之間有衝突。需要刪除導入的一些libs。
版 本 |
類 型 |
使用的library |
被忽略的library |
R Release |
單線程 |
libc.lib |
libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib |
多線程 |
libcmt.lib |
libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib |
使用DLL的多線程 |
msvcrt.lib |
libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib |
D Debug |
單線程 |
libcd.lib |
libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib |
多線程 |
libcmtd.lib |
libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib |
使用DLL的多線程 |
msvcrtd.lib |
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib |
例如編譯Release版本的單線程的工程,在linker的命令行加入如下的參數:
/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib
當然,通過VC6.0的開發環境也可以配置。選擇Project -> Setting,出現Project Setting對話框,單擊Link標籤,在Category下拉菜單中選擇Input,在下方的Ignore libraries: 輸入框中輸入“被忽略的library”框中對應的libs。輸入時注意當前Build是什麼版本,libs之間用“,”隔開。“Ingore all default libraries”不能勾選。
參考二
指定與你項目連接的運行期庫
/MT多線程應用程序
/Mtd多線程應用程序(DEBUG)
/MD多線程DLL
/MDd多線程DLL(DEBUG)
前段時間編譯一個引用自己寫的靜態庫的程序時老是出現鏈接時的多個重定義的錯誤,而自己的代碼明明沒有重定義這些東西,譬如:
LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: ___endstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __cflush already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __iob already defined in libc.lib(_file.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __alloc_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __set_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __free_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __get_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __open_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: __tolower already defined in libc.lib(tolower.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: _tolower already defined in libc.lib(tolower.obj)
等等。
所 以初步估計是編譯器的問題,通過網上搜索和查看msdn,原來是Visual C++ 編譯器選項的關於單線程或多線程運行時例程的問題:我的那個靜態庫編譯時/ML單線程版本的,而引用它的程序是/MT多線程版本的,他們在編譯分別將 libc.lib和LIBCMT.lib連接到各自的代碼中,估計libc.lib和LIBCMT.lib只是單線程與多線程的區別,基本代碼相差無幾, 所以會產生鏈接時重定義錯誤;然後把編譯靜態庫的選項/ML改成/MT就沒事了。
要注意的是:/MD也是多線程版本的;被應用的用戶鏈接庫 要和應用者有相同的編譯選項,/MD與/MT一起有時候會有錯誤的,有時候就沒有,我試過這種情況;而/MD和/ML似乎是沒有問題的;/MT和/ML是 肯定會有問題的。有沒有其他情況就不清楚了,有興趣的可以測試一下,^_^
如果是代碼是用於多線程的,最好編譯成多線程版本的,否則可能會出現一些意想不到的問題。
編譯器選項設置(vc6):工程 -> 設置 -> C/C++ -> 工程選項 裏可以修改
參考三
下面是msdn關於Visual C++ 編譯器選項的說明:
這些選項選擇單線程或多線程運行時例程,指示多線程模塊是否爲 DLL,並選擇運行時庫的發佈版本或調試版本。
選項 說明
/MD 定義 _MT 和 _DLL 以便同時從標準 .h 文件中選擇運行時例程的多線程特定版本和 DLL 特定版本。此選項還使編譯器將庫名 MSVCRT.lib 放入 .obj 文件中。
用此選項編譯的應用程序靜態鏈接到 MSVCRT.lib。該庫提供允許鏈接器解析外部引用的代碼層。實際工作代碼包含在 MSVCR71.DLL 中,該庫必須在運行時對於與 MSVCRT.lib 鏈接的應用程序可用。
當在定義了 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情況下使用 /MD 時,它將導致應用程序通過靜態多線程標準 C++ 庫 (libcpmt.lib) 而非動態版本 (msvcprt.lib) 進行鏈接,同時仍通過 msvcrt.lib 動態鏈接到主 CRT。
/MDd 定義 _DEBUG、_MT 和 _DLL,以便從標準 .h 文件中選擇運行時例程的調試多線程特定版本和 DLL 特定版本。它還使編譯器將庫名 MSVCRTD.lib 放入 .obj 文件中。
/ML 使編譯器將庫名 LIBC.lib 放入 .obj 文件中,以便鏈接器使用 LIBC.lib 解析外部符號。這是編譯器的默認操作。LIBC.lib 不提供多線程支持。
/MLd 定義 _DEBUG 並使編譯器將庫名 LIBCD.lib 放入 .obj 文件中,以便鏈接器使用 LIBCD.lib 解析外部符號。LIBCD.lib 不提供多線程支持。
/MT 定義 _MT, 以便從標準頭 (.h) 文件中選擇運行時例程的多線程特定版本。此選項還使編譯器將庫名 LIBCMT.lib 放入 .obj 文件中,以便鏈接器使用 LIBCMT.lib 解析外部符號。創建多線程程序需要 /MT 或 /MD(或它們的調試等效選項 /MTd 或 /MDd)。
/MTd 定義 _DEBUG 和 _MT。定義 _MT 會導致從標準 .h 文件中選擇運行時例程的多線程特定版本。此選項還使編譯器將庫名 LIBCMTD.lib 放入 .obj 文件中,以便鏈接器使用 LIBCMTD.lib 解析外部符號。創建多線程程序需要 /MTd 或 /MDd(或它們的非調試等效選項 /MT 或 MD)。
/LD 創建 DLL。
將 /DLL 選項傳遞到鏈接器。鏈接器查找 DllMain 函數,但並不需要該函數。如果沒有編寫 DllMain 函數,鏈接器將插入返回 TRUE 的 DllMain 函數。
/LDd 創建調試 DLL。定義 _DEBUG。
警告:
不要混合使用運行時庫的靜態版本和動態版本。在一個進程中有多個運行時庫副本會導致問題,因爲副本中的靜態數據不與其他副本共享。鏈接器禁止在 .exe 文件內部既使用靜態版本又使用動態版本鏈接,但您仍可以使用運行時庫的兩個(或更多)副本。例如,當與用動態 (DLL) 版本的運行時庫鏈接的 .exe 文件一起使用時,用靜態(非 DLL)版本的運行時庫鏈接的動態鏈接庫可能導致問題。(還應該避免在一個進程中混合使用這些庫的調試版本和非調試版本)。
有關使用運行時庫的調試版本的更多信息,請參見運行時庫參考。