LNK2019 是链接错误,表示编译通过但链接时找不到函数或变量的定义;主因是声明与定义不匹配、实现缺失、条件编译屏蔽、模板定义位置不当、C/C++ 名字修饰不一致等。
LNK2019 表示「找不到符号定义」——编译器已经顺利生成了 .obj 文件,但链

extern 或头文件里有声明)却没找到对应实现。典型现象是:代码能编译通过,运行前一步直接失败,错误信息末尾带 unresolved external symbol。
常见诱因不是语法错,而是工程结构或声明/定义不匹配:
#ifdef DEBUG 但当前是 Release 构建).h 中,但定义写在了另一个未加入项目的 .cpp 文件里extern "C" 声明,造成名字修饰(name mangling)不一致错误行末尾的 symbol 名字往往被修饰过(比如 ?myFunc@@YAXXZ),直接搜不到。先用 dumpbin /symbols 或 Visual Studio 的「属性 → 配置属性 → 链接器 → 调试 → 生成映射文件」打开 /MAP,再配合 undname 工具还原:
undname ?myFunc@@YAXXZ
输出类似 void __cdecl myFunc(void),就能确认它想找的是哪个函数。然后检查:
.cpp 中有定义?定义的签名(参数类型、const 修饰、重载)是否和声明完全一致?.cpp 是否已加入当前构建配置(右键文件 → 属性 → 常规 → “从生成中排除” 是否为“否”)?.lib)提供的符号,是否在「链接器 → 输入 → 附加依赖项」里加了对应 .lib 名?且该 .lib 路径已在「链接器 → 常规 → 附加库目录」中配置?类内定义的成员函数默认是 inline,但若把它拆成「头文件中声明 + 源文件中定义」,又没加 inline 关键字,就会触发 LNK2019(因为 inline 函数定义必须在每个使用它的编译单元都可见):
class A {
public:
void foo(); // 声明
};
如果 foo() 只在 A.cpp 里实现,而别的 .cpp 包含了 A.h 并调用了 foo(),链接器就找不到定义。解决办法二选一:
inline void foo() { ... })A.cpp 的内容移到 A.inl,并在 A.h 末尾 #include "A.inl"
extern 声明并确保只有一个定义源(非 inline 场景下,定义只能出现在一个 .cpp 中)当你在 C++ 里调用 C 写的 DLL 或静态库(比如 printf、sqlite3_open),但头文件没做 extern "C" 包裹,链接器会按 C++ 规则修饰名字,而库里导出的是 C 风格无修饰名,必然不匹配:
extern "C" {
#include "sqlite3.h"
}
同理,自己写的供 C 调用的函数,也得用 extern "C" 声明:
extern "C" __declspec(dllexport) int my_c_api_func(int x);
否则即使编译过,链接时也会报 LNK2019。另外注意:DLL 导入库(.lib)和头文件必须配套,版本不一致也可能导致符号名表面相同、实际不同。
这类问题最麻烦的地方在于:错误信息看不出是 C/C++ 混合导致的,得靠经验判断——如果符号名看起来“太干净”(比如 _my_c_api_func),而你的 C++ 代码里调用时没加 extern "C",那基本就是它了。