fatal error LNK1120:error LNK2001: 无法解析的外部符号

本文列举了多种导致LNK2001错误的原因及解决方案,包括代码问题如函数定义缺失、模板定义不当等,以及编译链接问题如库文件引用不当、编译选项配置错误等。



一、代码问题
  1.如果 LNK2001 诊断文本报告 __check_commonlanguageruntime_version 是无法解析的外部符号,在 function 中找到了未定义的外部符号 (symbol)。若要解决此错误,请提供符号定义或移除引用它的代码。
  2.成员模板的定义超出了类的范围。Visual C++ 的一个限制是,成员模板的定义必须完全位于封闭类内。
  3.代码中大小写不匹配
  4.如果项目使用函数内联,但在 .cpp 文件而非头文件中定义函数,则会导致 LNK2001。
  5.试图引用没有外部链接的函数或数据会导致 LNK2001。
  6.缺少函数主体或变量会导致 LNK2001。
  7.调用参数类型与函数声明中的参数类型不匹配的函数会导致 LNK2001。名称修饰将函数参数合并到最终修饰函数名中。
  8.错误包含的原型导致编译器需要没有提供的函数体,这样会导致 LNK2001。如果同时具有函数 F 的类实现和非类实现,请注意 C++ 范围解析规则。
  9.在使用 C++ 时,将函数原型包含在类定义中但未能包含实现(该类的此函数的实现)会导致 LNK2001。
  10.试图从抽象基类的构造函数或析构函数调用纯虚函数会导致 LNK2001。纯虚函数没有基类实现。
  11.试图在函数范围外使用用该函数声明的变量(局部变量)会导致 LNK2001。

二、编译和链接问题
   1.项目缺少对库 (.LIB) 或对象 (.OBJ) 文件的引用。有关更多信息,请参见用作链接器输入的 .lib 文件。
   2.如果使用 /NODEFAULTLIB 或 /Zl,包含所需代码的库将不会链接到项目,除非已显式地包括了这些库。(在使用 /clr 或 /clr:pure 进行编译时,您将看到对 .cctor 的引用;有关更多信息,请参见 混合程序集的初始化。)
   3.如果正在使用 Unicode 和 MFC,如果没有创建 wWinMainCRTStartup 的入口点,将在 _WinMain@16 上得到无法解析的外部对象;请使用 /ENTRY。请参见 Unicode 编程摘要。 
   4.将用 /MT 编译的代码与库 LIBC.lib 链接会在 _beginthread、_beginthreadex、_endthread 和 _endthreadex 上导致 LNK2001。
   5.链接需要多线程库的代码(任何 MFC 代码或用 /MT 编译的代码)会在 _beginthread、_beginthreadex、_endthread 和 _endthreadex 上导致 LNK2001。有关更多信息,请参见下列知识库文章: 
    6.在用 /MD 进行编译时,因为所有的运行时现在都存放在一个 DLL 中,所以源中的“func”引用在对象中变为“__imp__func”引用。如果试图与 LIBC.lib 或 LIBCMT.lib 静态库链接,则将在 __imp__func 上得到 LNK2001。当不用 /MD 进行编译时,如果试图与 MSVCxx.lib 链接,则并非总是得到 LNK2001,但可能会有其他问题。
   7.在生成应用程序的调试版本时与发布模式库链接会导致 LNK2001。同样,使用 /Mxd 选项(/MTd 或 /MDd)和/或定义 _DEBUG,然后再与版本库链接,将可能会产生无法解析的外部对象(同时还会出现其他问题)。将发布模式生成与调试库链接同样会导致类似问题。
   8.将 Microsoft 库版本和编译器产品版本混合可能会有问题。新编译器版本的库可能包含早期版本的库中没有的新符号。可能需要更改搜索路径中的目录顺序,或将它们更改为指向当前版本。
   9.使用库文件选择下的“工具”|“选项”|“项目”|“VC++ 目录”对话框,可以更改搜索顺序。项目的“属性页”对话框中的“链接器”文件夹可能也包含可能已过期的路径。
   10.当安装了新的 SDK(可能在不同的位置),但没有将搜索顺序更新为指向新位置时,可能会出现此问题。通常情况下,应将新 SDK 的 include 目录和 lib 目录的路径放在默认 Visual C++ 位置的前面。另外,包含嵌入路径的项目可能仍然指向旧路径,这些路径是有效的,但对于安装到不同位置的新版本所添加的新功能已过期。 
   11.编译器供应商之间、甚至同一编译器的不同版本之间当前没有 C++ 命名标准。因此,链接用其他编译器编译的对象文件可能无法生成相同的命名方案,从而导致错误 LNK2001。
   12.在不同模块上混合内联和非内联编译选项会导致 LNK2001。如果创建 C++ 库时打开了函数内联(/Ob1 或 /Ob2),但描述函数的相应头文件的内联是关闭的(没有 inline 关键字),则将发生此错误。若要防止此问题,请在要包含到其他文件中的头文件中用 inline 定义内联函数。
   13.如果使用 #pragma inline_depth 编译器指令,请确保具有 设置为 2 或更大的值,并确保使用 /Ob1 或 /Ob2 编译器选项。
   14.在创建纯资源 DLL 时省略 LINK 选项 /NOENTRY 将导致 LNK2001。
   15.使用不正确的 /SUBSYSTEM 或 /ENTRY 设置会导致 LNK2001。例如,如果编写基于字符的应用程序(控制台应用程序)并指定 /SUBSYSTEM:WINDOWS,您将得到无法解析的 WinMain 外部对象。有关这些选项和入口点的更多信息,请参见 /SUBSYSTEM 和 /ENTRY 链接器选项。

   关于代码问题1的第八种情况,不易发现,对于一般的函数而言,声明而不定义不会出现问题,然而对于消息响应函数,必须要要函数体的定义。

<< 这个错误 `fatal error LNK1120: unresolved external symbol` 是由 Microsoft 的链接器(linker)生成的一个常见错误信息。它表示链接阶段存在问题,具体来说,程序中引用了一个符号(通常是函数或变量),但链接器没有找到该符号的实际定义。 ### 错误原因及解决方案 #### 原因分析: 1. **缺少库文件**:如果使用了某个库中的功能,但是忘记将对应的 `.lib` 文件添加到项目设置的“附加依赖项”中,就会导致此问题。 2. **未实现声明的函数或变量**:如果在头文件中声明了一个全局函数、静态成员函数或变量,并且调用了它们,但在源文件中却没有提供实际定义,则会出现这个问题。 3. **拼写错误或其他语法问题**:例如大小写的不一致可能导致识别为两个不同标识符(虽然C++对此敏感,C语言相对宽松但仍需注意)。 4. **模块分离不当**:比如当一个非内联函数仅被申明而从未被真正编译进任何.obj目标文件时也会产生这样的情况。 5. **链接顺序错误**: 在某些情况下, 链接器要求特定类型的对象必须按照一定的次序进行处理. --- ### 示例代码与解决办法: 假设有一个简单的例子引发此类错误: ```c // foo.h #ifndef FOO_H_ #define FOO_H_ void myFunction(); // 函数声明 #endif /* FOO_H_ */ // main.c #include <stdio.h> #include "foo.h" int main(){ printf("Before calling myFunction\n"); myFunction(); return 0; } ``` 上述代码会因为`myFunction()`只有原型并没有具体的实现在别的地方所以报错. 我们需要确保所有使用的外部资源均有相应的实现部分如增加以下内容: ```c // foo.c #include <stdio.h> void myFunction() { puts("Hello from My Function!"); } ``` 然后保证这两个文件都被正确包含进了构建系统里并一同参与编译连接过程. --- ### 如何避免这种错误? - 检查所有的函数和变量是否都有其匹配的定义; - 当引入第三方库的时候要仔细阅读文档,确认已加入正确的.lib 或者.so 文件及其路径配置; - 使用IDE开发环境下可通过选项卡检查项目的输出类型以及所关联的其他组件列表等参数设定;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值