vs常見連結錯誤問題

2022-11-24 19:11:49 字數 4351 閱讀 8055

單執行緒 (libc.lib) 

多執行緒 (libcmt.lib) 

使用 dll 的多執行緒 (msvcrt.lib) 

除錯單執行緒 (libcd.lib) 

除錯多執行緒 (libcmtd.lib) 

使用 dll 的除錯多執行緒 (msvcrtd.lib) 

2、link : warning lnk4098: 預設庫“libcmtd”與其他庫的使用衝突;請使用 /nodefaultlib:library

以前經常遇到這個警告資訊,因為執行並沒有什麼問題,所以也沒深究。但是耿耿於懷那個“ 0 個錯誤,0 個警告”的成功提示,在網上搜了一下。原來問題出在預設庫的引用選擇上。

vs2008,專案——屬性——配置屬性——c/c++——**生成:他有/mt,/mtd,/md,/mdd四個選項,你必須讓所有使用的庫都使用相同的配置,否則就會有相應的提示,甚至可能會出現無法解析的函式。

有時我們使用的庫不是自己可以控制的,那麼就只能把工程屬性設定成河你使用的庫相同的選項。

錯誤 1 error lnk2005: _free 已經在 libcmtd.lib(dbgheap.obj) 中定義         msvcrt.lib

錯誤 2 error lnk2005: _malloc 已經在 libcmtd.lib(dbgheap.obj) 中定義     msvcrt.lib

如果有一堆的重定義錯誤發生在同一個lib中,而且跟它衝突的也是同一個lib,那麼這個兩個lib的功能應該是一樣的,可以2選一,只要在“忽略特定的庫”內填入需要忽略的庫。

專案屬性-配置屬性-常規-mfc的使用:在共享 dll 中使用 mfc

msvcrt.lib 和libcmt.lib的衝突還是比較常見的。

從錯誤資訊可以看出是msvcrt.lib和libcmt.lib庫中重複定義了__isctype等符號。為什麼會出現這樣的問題呢?這就要從這兩個庫的作用說起了。

msvcrt.lib是vc中的multithreaded dll 版本的c執行時庫,而libcmt.lib是multithreaded的執行時庫。在同一個專案中,所有的原始檔必須連結相同的c執行時庫。如果某一文 件用了multithreaded dll版本

,而其他檔案用了single-threaded或者multithreaded版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。

告警資訊的意思我們明白之後,就要找造成這個問題的原因了。在專案設定中我們可以看到當前專案使用的是multithreaded非dll版本的運 行時庫,這說明專案中還有其他檔案用到了不是這個版本的執行時庫。很顯然,就是openssl的靜態庫。檢視openssl中ms下的nt.mak,我們 可以發現靜態庫版本中openssl使用編譯開關/md進行編譯的,也就是說openssl靜態庫是預設用的multithreaded dll 版本的c執行時庫。

原因找到了。那麼解決方法,很明顯有兩個。總之就是將兩個專案的執行時庫統一。

簡單的方式就是將專案的動態庫修改為使用multithreaded dll 版本的c執行時庫即可。 某些情況下你的專案可能不能改變當前的執行時庫,你可以將openssl的nt.mak中的/md開關修改為/mt然後重新編譯openssl靜態庫就可以了。

預設庫“library”與其他庫的使用衝突;請使用 /nodefaultlib:library lnk4098 的解決辦法

您試圖與不相容的庫連結。

注意 執行時庫現在包含可防止混合不同型別的指令。如果試圖在同一個程式中使用不同型別的執行 時庫或使用除錯和非除錯版本的執行時庫,則將收到此警告。例如,如 果編譯一個檔案以使用一種執行時庫,

而編譯另一個檔案以使用另一種執行時庫(例如單執行緒執行時庫對多執行緒執行時庫),並試圖連結它們,則將得到此警告。應 將所有原始檔編譯為使用同一個執行時庫。有關更多資訊,請參見使用執行時庫(/md、/mt 和 /ld)編譯器選項。

可以 使用連結器的 /verbose:lib 開關來確定連結器搜尋的庫。如果收到 lnk4098,並想建立使用如單執行緒、非除錯執行時庫的可執行檔案,請使用 /verbose:lib 選項確定連結器搜尋的庫。

連結器作為搜尋的庫輸出的應是 libc.lib,而非 libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib 和 msvcrtd.lib。對每個要忽略的庫可以使用 /nodefaultlib,以通知連結器忽略錯誤的執行時庫。

下表顯示根據要使用的執行時庫應忽略的庫。

若要使用第一行執行時庫    請忽略第2行的這些庫 單執行緒 (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

除錯單執行緒 (libcd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcmtd.lib、msvcrtd.lib

除錯多執行緒 (libcmtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、msvcrtd.lib

使用 dll 的除錯多執行緒 (msvcrtd.lib) libc.lib、libcmt.lib、msvcrt.lib、libcd.lib、libcmtd.lib

/nodefaultlib:libcmt.lib /nodefaultlib:msvcrt.lib /nodefaultlib:libcd.lib /nodefaultlib:libcmtd.lib /nodefaultlib:msvcrtd.lib

解決:cannot open include file: 'inttypes.h'

可通過如下方法解決:

1、找到include目錄中的ffmpeg\common.h

2、在“#define common_h”之後加入如下**,同時刪除“#include ” 然後儲存:

#if defined(win32) && !defined(__mingw32__) && !defined(__cygwin__)

#    define config_win32

#endif

#if defined(win32) && !defined(__mingw32__) && !defined(__cygwin__) && !defined(emulate_inttypes)

#    define emulate_inttypes

#endif

#ifndef emulate_inttypes

#   include

#else  

typedef signed char  int8_t;   

typedef signed short int16_t;   

typedef signed int   int32_t;   

typedef unsigned char  uint8_t;    

typedef unsigned short uint16_t;   

typedef unsigned int   uint32_t;

#   ifdef config_win32     

typedef signed __int64   int64_t;       

typedef unsigned __int64 uint64_t;

#   else /* other os */      

typedef signed long long   int64_t;   

typedef unsigned long long uint64_t;

#   endif /* other os */

#endif /* emulate_inttypes */

解決error c3861: 'uint64_c': identifier not found

#ifndef int64_c

#define int64_c(c) (c ## ll)

#define uint64_c(c) (c ## ull)

#endif

ffmpeg.exe初始化出錯

進入mingw\bin目錄,通常是:c:\msys\mingw\bin\ 然後重新命名下述檔案:

c++-sjlj.exe to c++.exe

cpp-sjlj.exe to cpp.exe

g++-sjlj.exe to g++.exe

gcc-sjlj.exe to gcc.exe

然後再重新編譯,通常可以解決該問題。