链接错误:__imp__free_dbg等未解析外部符号(lib而非obj错误)
解决msvcprtd.lib链接时的__imp__free_dbg和__imp__malloc_dbg未定义错误
错误信息
1>msvcprtd.lib(locale0_implib.obj) : error LNK2019: 无法解析的外部符号 __imp__free_dbg,该符号在函数 "public: static void __cdecl std::_Fac_node::operator delete(void *)" (??3_Fac_node@std@@SAXPEAX@Z) 中被引用 1>msvcprtd.lib(locale0_implib.obj) : error LNK2019: 无法解析的外部符号 __imp__malloc_dbg,该符号在函数 "public: static void * __cdecl std::_Fac_node::operator new(unsigned __int64)" (??2_Fac_node@std@@SAPEAX_K@Z) 中被引用 1>C:\Users\asdfs\source\repos\Debugger\x64\Debug\Debugger.exe : fatal error LNK1120: 2 个无法解析的外部命令
问题根源
从提供的编译、链接命令和项目文件来看,核心问题是编译配置与输出目录/链接配置不匹配:
- 编译命令使用了
/MDd(动态调试版CRT)、/ZI(编辑并继续)、/RTC1(运行时错误检查)等Debug模式专属参数,但输出目录却指向x64\Release,属于Release路径; - 链接时手动指定了
msvcrtd.lib,但配置混用导致C++标准库调试版(msvcprtd.lib)无法正确找到CRT调试库中的内存分配符号。
解决方案
1. 统一编译配置(优先选择)
根据实际需求选择Debug或Release模式,统一所有参数:
- 如果编译Release版本:
把编译命令中的/MDd改为/MD(Release版动态CRT),移除/ZI、/RTC1,添加/O2(优化)参数,确保输出目录为x64\Release。 - 如果编译Debug版本:
保持/MDd、/ZI、/RTC1参数,将输出目录改为x64\Debug,确保所有配置与Debug模式一致。
2. 修正链接库配置
避免手动指定CRT相关库,让编译器自动匹配:
- 移除链接命令中手动添加的
msvcrtd.lib,VS会根据编译时的/MDd或/MD参数,自动链接对应的CRT库和C++标准库,避免因库顺序问题导致的符号缺失。
3. 检查项目属性一致性
通过VS项目属性界面统一配置,避免命令行参数混乱:
- 右键项目→属性→配置属性→C/C++→代码生成:选择对应模式的“运行时库”(Debug选
多线程调试 DLL (/MDd),Release选多线程 DLL (/MD)); - 配置属性→C/C++→常规:“调试信息格式”与配置匹配(Debug用
/ZI,Release用/Zi); - 配置属性→链接器→输入:清空“附加依赖项”中的
msvcrtd.lib,依赖由编译器自动处理。
附:用户提供的项目文件与错误配置
DebugLoop.h
#pragma once #include <windows.h> #include <iostream> #include <ostream> DWORD OnCreateThreadDebugEvent(const LPDEBUG_EVENT); DWORD OnCreateProcessDebugEvent(const LPDEBUG_EVENT); DWORD OnExitThreadDebugEvent(const LPDEBUG_EVENT); DWORD OnExitProcessDebugEvent(const LPDEBUG_EVENT); DWORD OnLoadDllDebugEvent(const LPDEBUG_EVENT); DWORD OnUnloadDllDebugEvent(const LPDEBUG_EVENT); DWORD OnOutputDebugStringEvent(const LPDEBUG_EVENT); DWORD OnRipEvent(const LPDEBUG_EVENT); void EnterDebugLoop(const LPDEBUG_EVENT DebugEv);
main.cpp
#include <iostream> #include <windows.h> #include <psapi.h> #include "DebugLoop.h" #pragma comment(lib, "Psapi.lib") int main(int argc, char *argv[]) { STARTUPINFOA si; PROCESS_INFORMATION pi; DEBUG_EVENT dbgEvent; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&dbgEvent, sizeof(dbgEvent)); if (argc != 2) { printf("用法: %s [命令行]\n", argv[0]); return 1; } // 启动子进程 if (!CreateProcessA(NULL, // 无模块名称(使用命令行) argv[1], // 命令行 NULL, // 进程句柄不可继承 NULL, // 线程句柄不可继承 FALSE, // 设置句柄继承为FALSE 0, // 无创建标志 NULL, // 使用父进程环境块 NULL, // 使用父进程启动目录 &si, // STARTUPINFO结构指针 &pi) // PROCESS_INFORMATION结构指针 ) { printf("CreateProcess失败 (%d).\n", GetLastError()); return 1; } // 等待子进程退出 if (WaitForDebugEventEx(&dbgEvent, INFINITE) > 0) EnterDebugLoop(&dbgEvent); // 关闭进程和线程句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }
错误编译命令
/JMC /ifcOutput "x64\Release\" /GS /W1 /Zc:wchar_t /ZI /Gm- /Od /Fd"x64\Release\vc143.pdb" /Zc:inline /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /Fa"x64\Release\" /EHsc /Fo"x64\Release\" /FAcs /Fp"x64\Release\Debugger.pch" /diagnostics:column
错误链接命令
/OUT:"C:\Users\asdfs\source\repos\Debugger\x64\Release\Debugger.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\asdfs\source\repos\Debugger\x64\Release\Debugger.pdb" /DYNAMICBASE "msvcrtd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FULL /MACHINE:X64 /INCREMENTAL /PGD:"C:\Users\asdfs\source\repos\Debugger\x64\Release\Debugger.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Release\Debugger.exe.intermediate.manifest" /LTCGOUT:"x64\Release\Debugger.iobj" /ERRORREPORT:PROMPT /ILK:"x64\Release\Debugger.ilk" /VERBOSE /TLBID:1
内容的提问来源于stack exchange,提问作者winapiadmin
相关产品推荐
相关产品推荐

