錯誤現場
LINK : warning LNK4098: defaultlib "LIBCMTD" conflicts with use of other libs
Sort.obj : error LNK2001: unresolved external symbol __security_cookie
... (多個 __RTC_*, @__security_check_cookie@4 等)
fatal error LNK1120: 6 unresolved externals
根本原因:專案內混用不同** C 運行時庫 (CRT) 版本**
| CRT 版本 | 編譯選項 | 特徵 | 適用庫 |
| 單執行緒 | /ML (已棄用) | 舊版 | LIBC.lib |
| 多執行緒靜態 | /MT | CRT 靜態連結進 exe | LIBCMT.lib |
| 多執行緒靜態偵錯 | /MTd | 含偵錯檢查 | LIBCMTD.lib |
| 多執行緒動態 | /MD | 載入 msvcrt.dll / vcruntime140.dll | MSVCRT.lib |
| 多執行緒動態偵錯 | /MDd | 載入 msvcrtd.dll | MSVCRTD.lib |
衝突場景
- 主專案用
/MTd,引用的靜態庫 (如 OpenSSL) 用 /MD 編譯。
- 專案內不同 .c 檔設定不同
Code Generation 選項。
- NuGet/手動引入的預編譯庫與專案設定不一致。
解決方案:統一 CRT 版本
方法一:修改專案設定 (最簡單)
專案右鍵 → Properties → C/C++ → Code Generation → **Runtime Library** → 全專案統一選擇:
- Release 建議
/MD (動態、體積小、安全更新自動獲取)。
- Debug 對應
/MDd。
- 若必須靜態連結 (無法部署 DLL),全專案用
/MT / /MTd,並重新編譯**所有**靜態庫。
方法二:忽略衝突庫 (治標)
Linker → Input → Ignore Specific Default Libraries → 加入衝突庫名:
LIBCMTD.lib; MSVCRTD.lib; LIBCMT.lib; MSVCRT.lib
// 視實際警告保留需要的,刪除衝突的
⚠️ 可能導致執行期崩潰 (heap 損壞、雙重 free),**不推薦生產環境**。
方法三:重新編譯第三方庫 (徹底)
- 取得庫原始碼 (如 OpenSSL)。
- 修改其建置腳本 (
Configure/CMakeLists.txt/.vcxproj) 將 CRT 選項改為與主專案一致。
- 重新編譯產生 .lib,替換專案引用。
偵錯檢查清單
dumpbin /directives your.lib 查看庫依賴的 CRT (尋找 DEFAULTLIB:LIBCMT 等)。
- 專案 → Properties → C/C++ → Command Line → 檢查實際傳遞的
/MD /MT 等選項。
- 清理解決方案 → 重新建置 (殘留 .obj 可能導致舊設定殘留)。
最佳實踐
- **公司/團隊層面統一 CRT 政策**:所有內部庫、專案強制同一選項 (推薦
/MD / /MDd)。
- 使用 **CMake** 管理建置,統一
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug$>$")。
- 引入第三方庫優先尋找 **已配置好 CRT 的預編譯包** (vcpkg、Conan、NuGet)。
- 上一篇文章: C語言浮點數保留兩位小數:輸出格式化 vs 數值四捨五入的正確選擇
- 下一篇文章: C語言 for 迴圈實戰:紙張疊加超越珠峰高度
Copyright ©
程式碼之家 All Rights Reserved