Mr.J--C语言学习Errors:LNK2019
每日日常敲代码,日常看bug,错误提示:
这个错误提示第一次见到,心里表示很难受于是乎google一下:
可以在Linker Tools Error LNK2019中找到该主题的最新版本。
函数'function'中引用的未解析的外部符号'symbol'
链接器找不到symbol
函数“ function
”中使用的外部符号“ ” 的定义。
有许多问题可能导致此错误。本主题将帮助您确定原因并找到解决方案。
一个符号是编译器使用的函数或全局变量的名称。一个外部符号是用来指的是在不同来源或对象文件中定义的符号的名称。链接器必须为每个编译文件链接到应用程序或DLL时使用的每个函数或全局变量解析或找到外部符号的定义。如果链接器无法在任何链接文件中找到外部符号的匹配定义,则会生成LNK2019。
如果构建中未包含具有符号定义的对象或库文件,则会发生此错误。如果链接器搜索的符号名称与库中的符号名称或定义它的目标文件不匹配,也会发生这种情况。如果调用代码中的名称拼写错误,使用不同的大小写,使用不同的调用约定或指定不同的参数,则会发生这种情况。
使用C ++链接的代码使用名称修饰(也称为名称修改)来编码有关变量或函数类型的额外信息,并在符号名称中调用约定。该修饰名是链接器搜索以解析外部符号的名称。因为类型信息成为符号的修饰名称的一部分,所以如果使用它的外部符号的声明与定义它的符号的声明不匹配,则可能导致LNK2019。为了帮助您找到错误原因,错误消息显示“友好名称”,源代码中使用的名称以及未解析外部符号的修饰名称(括号中)。您不需要知道如何翻译装饰名称以便能够将其与其他装饰名称进行比较。
常见问题
以下是导致LNK2019的一些常见问题:
包含符号定义的目标文件或库未链接。在Visual Studio中,验证包含该定义的源文件是否已构建并链接为项目的一部分。在命令行上,验证是否已编译包含该定义的源文件,以及生成的目标文件是否包含在要链接的文件列表中。
符号的声明与拼写的定义拼写不同。验证声明和定义中使用的拼写和大小写是否正确,以及使用或调用符号的位置。
使用了一个函数,但参数的类型或数量与函数定义不匹配。函数声明必须与定义匹配。验证函数调用是否与声明匹配,以及声明是否与定义匹配。调用模板函数的代码还必须具有匹配的模板函数声明,其中包含与定义相同的模板参数。有关模板声明不匹配的示例,请参阅示例部分中的示例LNK2019e.cpp。
声明了函数或变量但未定义。这通常意味着头文件中存在声明,但未实现匹配的定义。对于成员函数或静态数据成员,实现必须包括类作用域选择器。有关示例,请参阅缺少函数体或变量。
函数声明和函数定义之间的调用约定是不同的。调用约定(__cdecl,__stdcall,__fastcall,或__vectorcall)被编码为装饰名称的一部分。验证调用约定是否相同。
符号在C文件中定义,但在C ++文件中未使用extern“C”进行声明。编译为C的文件中定义的符号具有与C ++文件中声明的符号不同的装饰名称,除非您使用extern“C”修饰符。验证声明是否与每个符号的编译链接匹配。
同样,如果在C程序
extern "C"
中定义将由C程序使用的符号,请在定义中使用。符号定义为静态,然后在文件外引用。在C ++中,与C不同,全局常量具有
static
链接。要解决此限制,可以const
在头文件中包含初始化并在.cpp文件中包含该头,或者可以使变量非常量并使用常量引用来访问它。未定义类的静态成员。静态类成员必须具有唯一定义,否则将违反单定义规则。无法在内定义的静态类成员必须使用其完全限定名称在一个源文件中定义。如果根本没有定义,链接器将生成LNK2019。
构建依赖关系仅在解决方案中定义为项目依赖关系。在早期版本的Visual Studio中,此级别的依赖性已足够。但是,从Visual Studio 2010开始,Visual Studio需要项目到项目的引用。如果您的项目没有项目到项目引用,则可能会收到此链接器错误。添加项目到项目的引用以修复它。
您可以使用Windows应用程序的设置来构建控制台应用程序。如果错误消息类似于函数中引用的未解析的外部符号WinMain
function_name
,则使用/ SUBSYSTEM:CONSOLE而不是/ SUBSYSTEM:WINDOWS进行链接。有关此设置的详细信息,以及有关如何在Visual Studio中设置此属性的说明,请参阅/ SUBSYSTEM(指定子系统)。您可以使用不同的编译器选项在不同的源文件中进行函数内联。使用.cpp文件中定义的内联函数和混合函数内联不同源文件中的编译器选项可能会导致LNK2019。有关更多信息,请参阅函数内联问题。
您在其范围之外使用自动变量。自动(函数范围)变量只能在该函数的范围内使用。无法
extern
在其他源文件中声明和使用这些变量。有关示例,请参见自动(函数范围)变量。您可以调用instrinsic函数或将参数类型传递给目标体系结构不支持的内部函数。例如,如果使用AVX2内在函数,但未指定/ ARCH:AVX2编译器选项,则编译器会假定内在函数是外部函数。编译器不会生成内联指令,而是生成对与内在符号同名的外部符号的调用。当链接器尝试查找此缺失函数的定义时,它会生成LNK2019。确认您仅使用目标体系结构支持的内在函数和类型。
您将使用本机wchar_t的代码与不使用本机wchar_t的代码混合在一起。在Visual C ++ 2005中完成的C ++语言一致性工作
wchar_t
默认情况下是一个本机类型。必须使用/ Zc:wchar_t-编译器选项生成与使用早期版本的Visual C ++编译的库和目标文件兼容的代码。如果并非所有文件都使用相同的/ Zc:wchar_t设置进行编译,则类型引用可能无法解析为兼容类型。wchar_t
通过更新所使用的类型或在编译时使用consistent / Zc:wchar_t设置来验证所有库和目标文件中的类型是否兼容。
有关LNK2019的可能原因和解决方案的更多信息,请参阅堆栈溢出问题什么是未定义的参考/未解决的外部符号错误以及如何解决?。
诊断工具
很难说为什么链接器找不到特定的符号定义。通常问题是您没有在构建中包含代码,或者构建选项为外部符号创建了不同的装饰名称。有几个工具和选项可以帮助您诊断LNK2019错误。
该/ VERBOSE链接器选项可以帮助你确定哪些文件链接引用。这可以帮助您验证包含符号定义的文件是否包含在您的构建中。
DUMPBIN实用程序的/ EXPORTS和/ SYMBOLS选项可以帮助您发现.dll和对象或库文件中定义的符号。验证导出的修饰名称是否与链接器搜索的修饰名称匹配。
UNDNAME实用程序可以显示装饰名称的等效未修饰外部符号。
例子
以下是导致LNK2019错误的几个代码示例,以及有关如何修复错误的信息。
声明符号但未定义
以下示例生成LNK2019,因为已声明外部符号但未定义:
C ++
// LNK2019.cpp
//使用以下
命令 编译:cl / EHsc LNK2019.cpp // LNK2019预期
extern char B [100]; // B不可用于链接器
int main(){ B [0] =''; // LNK2019
}
这是另一个例子:
C ++
// LNK2019c.cpp
//使用以下
命令 编译:cl / EHsc LNK2019c.cpp // LNK2019预期
extern int i;
extern void g();
void f(){ 我++; G();
}
int main(){}
如果在构建中的某个文件中定义i
和g
未定义,则链接器将生成LNK2019。您可以通过将包含定义的源代码文件包含在编译中来修复错误。或者,您可以传递包含定义的链接器.obj文件或.lib文件。
声明了静态数据成员但未定义
当声明静态数据成员但未定义静态数据成员时,也会发生LNK2019。以下示例生成LNK2019,并显示如何修复它。
C ++
// LNK2019b.cpp
//使用以下
命令 编译:cl / EHsc LNK2019b.cpp // LNK2019预期
struct C { static int s;
}; //取消注释以下行以修复错误。
// int C :: s; int main(){ C c; C :: s = 1;
}
声明参数与定义不匹配
调用模板函数的代码必须具有匹配的模板函数声明。声明必须包含与定义相同的模板参数。以下示例在用户定义的运算符上生成LNK2019,并显示如何修复它。
C ++
// LNK2019e.cpp
//使用以下
命令 编译:cl / EHsc LNK2019e.cpp //预计LNK2019
#include <iostream>
使用 命名空间 std; template < class T> 类
测试{ // operator <<声明与下面的定义不匹配: friend ostream&operator <<(ostream&,Test&); //要修复,请使用以下内容替换上面的行: // template <typename T> friend ostream&operator <<(ostream&,Test <T>&);
}; template < typename T>
ostream&operator <<(ostream&os,Test <T>&tt){ return os;
} int main(){ 测试< int > t; cout << “测试:” << t << endl; // LNK2019未解析外部
}
wchar_t类型定义不一致
下面的示例创建一个具有导出使用的DLL WCHAR
,该解析将解析为wchar_t
。
C ++
// LNK2019g.cpp
//编译:cl / EHsc / LD LNK2019g.cpp
#include “windows.h”
// WCHAR解析为wchar_t
__declspec(dllexport)void func(WCHAR *){}
以下示例使用上一个示例中的DLL,并生成LNK2019,因为unsigned short *和WCHAR *类型不同。
C ++
// LNK2019h.cpp
//使用以下
命令 编译:cl / EHsc LNK2019h LNK2019g.lib // LNK2019期望
__declspec(dllimport)void func(unsigned short *); int main(){ FUNC(0);
}
要解决此错误,请使用/ Zc:wchar_t-更改unsigned short
为wchar_t
或WCHAR
编译LNK2019g.cpp。
经过细心察看发现函数名的参数与我在头函数定义的参数类型不匹配,一个bug已经消除,新的bug又来了...
Mr.J--C语言学习Errors:LNK2019相关推荐
- c语言行列坐标是先行后j,C语言学习之行列操作
C语言学习之队列操作 本文件为队列操作的接口: /*queue.h*/ #ifndef _SEQQUEUE_H_ #define _SEQQUEUE_H_ #define QUEUE_MAX 15 t ...
- go语言学习初探(二)基础语法
变量声明 var v1 int var v2 string var v3 [10]int var v4 []int var v5 struct {f int } var v6 *int var v7 ...
- 【Go语言 · 学习笔记】
文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...
- R语言学习手记 (1)
R语言学习手记 (1) 经管的会计和财管都会学数据统计与分析R语言这门课,加上我也有点兴趣,就提前选了这门课,以下的笔记由老师上课的PPT.<R语言编程艺术>和<R语言数据科学> ...
- C语言学习趣事_之_大数运算_加法
C语言学习趣事_大数运算_之加法 1.引子 在C语言中,因为预定义的自然数类型的大小是有上下限度的,这就决定了在进行数的运算的时候,必然受到限制,同时因为C语言是最接近汇编的一种程序设计语言,并 ...
- Python语言学习:Python常用自带库(imageio、pickle)简介、使用方法之详细攻略
Python语言学习:Python常用自带库(imageio.pickle)简介.使用方法之详细攻略 目录 imageio简介及其常见使用方法 pickle简介及其常见使用方法 简介 使用方法 简介及 ...
- c 语言学习:基本操作,数组,字符串,指针
文章目录 基本操作 判断闰年平年 倒序输出五位数 赋值运算 用条件表达式求三个数的最大值 测试int,float,char类型在本机所占的字节数 单个字符的输入getchar() 使用*抑制符跳过输入 ...
- C语言学习之用*打印菱形
C语言学习之用*打印菱形 #include <stdio.h> int main(){int i,j,k;//定义变量for(i=0;i<=3;i++){ //控制菱形的前三行for ...
- 12天学好C语言——记录我的C语言学习之路(Day 12)
12天学好C语言--记录我的C语言学习之路 Day 12: 进入最后一天的学习,用这样一个程序来综合考量指针和字符串的关系,写完这个程序,你对字符串和指针的理解应该就不错了. //输入一个字符串,内有 ...
最新文章
- 导致美国大范围网络瘫痪的Mirai僵尸网络
- HDU1527(博弈论)
- Android 画虚线边框
- C++语言程序设计之关联容器类型
- mysql limit的使用方法
- [二叉树] 二叉树的最近公共祖先--leetcode236
- js 实时监听input中值变化
- SAP OData $batch processing
- UVA11413 Fill the Containers【二分搜索】
- bzoj 1406: [AHOI2007]密码箱
- PHP踩坑:对象的引用
- 【风电功率预测】基于matlab灰狼算法优化LSTM风电功率预测【含Matlab源码 1392期】
- Internet Download Manager 6.37.14 Final
- 如何在学习中找到乐趣?怎样才能找到学习的乐趣
- 智能家居小知识普及篇——智能家居技术有哪些劣势
- HTTP 代理服务器的设计与实现
- 【礼物】的定义不同所造成的诡异反差感
- Gentoolinux安装教程
- 什么是CLI(命令行界面)、GUI(图形用户界面)、Terminal(终端)、Console(控制台)、Shell、TTY
- 《python3网络爬虫开发实战》学习笔记:pc与安卓代理证书都安装好但是无法监听——记自己的踩坑路径