VC++的链接错误LNK2001

本文详细介绍了在使用VC++开发过程中常见的链接错误LNK2001及其产生的多种原因,包括编码错误、编译链接设置不当等,并提供了具体的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

帖子转自zhhxidian2005的博客

博客地址为:http://blog.youkuaiyun.com/zhhxidian2005/archive/2007/06/06/1641371.aspx

感谢作者提供内容!

 

 

 

 

 


晚风也渡 发表于 2003-1-9 17:51:45
主题 VC++的链接错误LNK2001(ZT)

学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于
编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,
编译都已通过。产生连接错误的原因非常多,尤其LNK2001错误,常常使人不
明其所以然。如果不深入地学习和理解VC++,要想改正连接错误LNK2001非
常困难。
  初学者在学习VC++的过程中,遇到的LNK2001错误的错误消息主要为:
  unresolved external symbol “symbol”(不确定的外部“符号”)。
  如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或
标签,将产生此错误消息。一般来说,发生错误的原因有两个:一是所引用
的函数、变量不存在、拼写不正确或者使用错误;其次可能使用了不同版本
的连接库。
  以下是可能产生LNK2001错误的原因:
  一.由于编码错误导致的LNK2001。
  1.不相匹配的程序代码或模块定义(.DEF)文件能导致LNK2001。例如,
如果在C++ 源文件内声明了一变量“var1”,却试图在另一文件内以变量
“VAR1”访问该变量,将发生该错误。
  2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定
义将导致LNK2001错误。
  3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生
LNK2001。
  4.试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001。
  5.要注意函数和变量的可公用性,只有全局变量、函数是可公用的。
  静态函数和静态变量具有相同的使用范围限制。当试图从文件外部访问
任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001。
  函数内声明的变量(局部变量) 只能在该函数的范围内使用。
  C++ 的全局常量只有静态连接性能。这不同于C,如果试图在C++的
多个文件内使用全局变量也会产生LNK2001错误。一种解决的方法是需要时在
头文件中加入该常量的初始化代码,并在.CPP文件中包含该头文件;另一种
方法是使用时给该变量赋以常数。
  二.由于编译和链接的设置而造成的LNK2001
  1.如果编译时使用的是/NOD(/NODEFAULTLIB)选项,程序所需要的运行
库和MFC库在连接时由编译器写入目标文件模块, 但除非在文件中明确包含
这些库名,否则这些库不会被链接进工程文件。在这种情况下使用/NOD将导
致错误LNK2001。
  2.如果没有为wWinMainCRTStartup设定程序入口,在使用Unicode和MFC
时将得到“unresolved external on _WinMain@16”的LNK2001错误信息。
  3.使用/MD选项编译时,既然所有的运行库都被保留在动态链接库之内,
源文件中对“func”的引用,在目标文件里即对“__imp__func” 的引用。
如果试图使用静态库LIBC.LIB或LIBCMT.LIB进行连接,将在__imp__func上发
生LNK2001;如果不使用/MD选项编译,在使用MSVCxx.LIB连接时也会发生LNK2001。
  4.使用/ML选项编译时,如用LIBCMT.LIB链接会在_errno上发生LNK2001。
  5.当编译调试版的应用程序时,如果采用发行版模态库进行连接也会产
生LNK2001;同样,使用调试版模态库连接发行版应用程序时也会产生相同的
问题。
  6.不同版本的库和编译器的混合使用也能产生问题,因为新版的库里可
能包含早先的版本没有的符号和说明。
  7.在不同的模块使用内联和非内联的编译选项能够导致LNK2001。如果
创建C++库时打开了函数内联(/Ob1或/Ob2),但是在描述该函数的相应头
文件里却关闭了函数内联(没有inline关键字),这时将得到该错误信息。
为避免该问题的发生,应该在相应的头文件中用inline关键字标志内联函数。
  8.不正确的/SUBSYSTEM或/ENTRY设置也能导致LNK2001。
  其实,产生LNK2001的原因还有很多,以上的原因只是一部分而已,对初
学者来说这些就够理解一阵子了。但是,分析错误原因的目的是为了避免错
误的发生。LNK2001错误虽然比较困难,但是只要注意到了上述问题,还是能
够避免和予以解决的。

 

 

msdn给的说明

http://msdn.microsoft.com/en-us/library/aa234493(VS.60).aspx

 

 

 

Linker Tools Error LNK2001

Visual Studio 6.0

unresolved external symbol "symbol"

Code will generate this error message if it references something (like a function, variable, or label) that the linker can’t find in all the libraries and object files it searches. In general, there are two reasons this error occurs: what the code asks for doesn’t exist (the symbol is spelled incorrectly or uses the wrong case, for example), or the code asks for the wrong thing (you are using mixed versions of the libraries?some from one version of the product, others from another version).

Numerous kinds of coding and build errors can cause LNK2001. Several specific causes are listed below, and some have links to more detailed explanations.

Coding Problems

  • Mismatched case in your code or module-definition (.DEF) file can cause LNK2001. For example, if you named a variable “var1” in one C++ source file and tried to access it as “VAR1” in another, you would receive this error. The solution is to exactly match the case of the symbol in all references.
  • A project that uses function inlining yet defines the functions in a .CPP file rather than in the header file can cause LNK2001. 
  • If you are using C++, make sure to use extern “C” when calling a C function from a C++ program. By using extern “C” you force the use of the C naming convention. Be aware of compiler switches like /Tp or /Tc that force a file to be compiled as a C (/Tc) or C++ (/Tp) file no matter what the filename extension, or you may get different function names than you expect.
  • Attempting to reference functions or data that don't have external linkage causes LNK2001. In C++, inline functions and const data have internal linkage unless explicitly specified as extern
  • missing function body or variable will cause LNK2001. Having just a function prototype or extern declaration will allow the compiler to continue without error, but the linker will not be able to resolve your call to an address or reference to a variable because there is no function code or variable space reserved. 
  • Name decoration incorporates the parameters of a function into the final decorated function name. Calling a function with parameter types that do not match those in the function declaration may cause LNK2001. 
  • Incorrectly included prototypes will cause the compiler to expect a function body that is not provided. If you have both a class and non-class implementation of a function F, beware of C++ scope-resolution rules. 
  • When using C++, make sure that you include the implementation of a specific function for a class and not just a prototype in the class definition. 
  • Attempting to call a pure virtual function from the constructor or destructor of an abstract base class will cause LNK2001 since by definition a pure virtual function has no base class implementation. 
  • Only global functions and variables are public.

    Functions declared with the static modifier by definition have file scope. Static variables have the same limitation. Trying to access any static variables from outside of the file in which they are declared can result in a compile error or LNK2001.

    A variable declared within a function (a local variable) can only be used within the scope of that function.

    C++ global constants have static linkage. This is different than C. If you try to use a global constant in C++ in multiple files you get error LNK2001. One alternative is to include the const initializations in a header file and include that header in your .CPP files when necessary, just as if it was a function prototype. Another alternative is to make the variable non-constant and use a constant reference when assessing it.

Compiling and Linking Problems

  • The names of the Microsoft run-time and MFC libraries needed at link time are included in the object file module by the Microsoft compiler. If you use the /NOD (/NODEFAULTLIB) option, these libraries will not be linked into the project unless you have explicitly included them. Using /NOD will cause error LNK2001 in this case. 
  • If you are using Unicode and MFC, you will get an unresolved external on _WinMain@16 if you don’t create an entrypoint towWinMainCRTStartup. Use the /ENTRY option or type this value in the Project Settings dialog box. (To find this option in the development environment, click Settings on the Project menu, then click the Link tab, and click Output in the Category box.) SeeUnicode Programming Summary

    See the following Knowledge Base articles located in the Online Information System for more information. An easy way to reach an article is to copy a "Q" number above, open the Search dialog box from the Help menu and select the Query tab, then paste the number into the first text box and press ENTER.
    • Q125750   "PRB: Error LNK2001: '_WinMain@16': Unresolved External Symbol"
    • Q131204   "PRB: Wrong Project Selection Causes LNK2001 on _WinMain@16"
    • Q100639   "Unicode Support in the Microsoft Foundation Class Library"
  • Linking code compiled with /MT with the library LIBC.LIB causes LNK2001 on _beginthread_beginthreadex_endthread, and_endthreadex
  • When compiling with /MD, a reference to "func" in your source becomes a reference "__imp__func" in the object since all the run-time is now held within a DLL. If you try to link with the static libraries LIBC.LIB or LIBCMT.LIB, you will get LNK2001 on __imp__func. If you try to link with MSVCxx.LIB when compiling without /MD you will not always get LNK2001, but you will likely have other problems. 
  • Linking code compiled with an explicit or implicit /ML to the LIBCMT.LIB causes LNK2001 on _errno
  • Linking with the release mode libraries when building a debug version of an application can cause LNK2001. Similarly, using an /Mxd option (/MLd, /MTd, or /MDd) and/or defining _DEBUG and then linking with the release libraries will give you potential unresolved externals (among other problems). Linking a release mode build with the debug libraries will also cause similar problems.
  • Mixing versions of Microsoft libraries and compiler products can be problematic. A new compiler version's libraries may contain new symbols that cannot be found in the libraries included with previous versions. Use DUMPBIN to find out if a symbol is in a 32-bit object file or library. 
  • There is currently no standard for C++ naming between compiler vendors or even between different versions of a compiler. Therefore linking object files compiled with other compilers may not produce the same naming scheme and thus cause error LNK2001.
  • Mixing inline and non-inline compile options on different modules can cause LNK2001. If a C++ library is created with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the functions has inlining turned off (no inline keyword), you will get this error. To prevent this problem, have the inline functions defined with inline in the header file you are going to include in other files.
  • If you are using the #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set, and make sure you are using the /Ob1 or /Ob2 compiler option. 
  • Omitting the LINK option /NOENTRY when creating a resource-only DLL will cause LNK2001.
  • Using incorrect /SUBSYSTEM or /ENTRY settings can cause LNK2001. For example, if you write a character-based application (a console application) and specify /SUBSYSTEM:WINDOWS, you will get an unresolved external for WinMain. For more information on these options and entry points, see the /SUBSYSTEM and /ENTRY linker options.

Export Problems

  • When you are porting an application from 16 to 32 bits, LNK2001 can occur. The current 32-bit module-definition (.DEF) file syntax requires that __cdecl__stdcall, and __fastcall functions be listed in the EXPORTS section without underscores (undecorated). This differs from the 16-bit syntax, where they must be listed with underscores (decorated). For more information, see the description of theEXPORTS section of module-definition files. 
  • Any export listed in the .DEF file and not found will cause LNK2001. This could be because it does not exist, is spelled incorrectly, or uses decorated names (.DEF files do not take decorated names). 

This error message is followed by fatal error LNK1120.

The following sections give more detailed information on some of the issues named in the above list.

 

 

### MFC项目中解决LNK2001未解析的外部符号错误 在MFC项目开发过程中,当导入外部头文件并尝试调用其中定义的功能时,可能会遇到`LNK2001 unresolved external symbol`错误。此错误通常表明编译器能够识别声明的函数或变量名称(通过头文件),但在链接阶段无法找到这些符号的实际实现。 #### 错误原因分析 该问题的根本原因是链接器未能成功定位到所需功能的具体实现代码。这可能由以下几个因素引起: - **缺少必要的库文件**:虽然包含了正确的头文件,但如果对应的静态或动态库(.lib/.dll)未被正确指定,则会出现此类错误[^2]。 - **配置不匹配**:如果项目的构建设置(如调试/发布模式、多线程DLL vs 静态CRT等)与目标库的版本不符,也可能引发这种链接错误。 - **路径缺失**:即使指定了正确的库名,在某些情况下还需要提供额外的目录信息以便于查找相关资源。 #### 解决方法概述 针对上述情况,可以采取如下措施来解决问题: ##### 方法一: 添加相应的库文件至工程设置 对于特定类型的API或者框架支持, 可能需要显式地告诉编译环境去寻找哪个具体的`.lib`文件作为补充材料的一部分参与最终程序组装过程. 例如处理视频捕获相关的操作需要用到 `VFW32.lib`, 则应该按照以下步骤执行: 1. 打开Visual Studio中的Project属性页; 2. 转向 "Linker" -> "Input"; 3. 将对应库的名字追加进 "Additional Dependencies", 如这里提到的例子就是输入字符串形式表示的一个条目:`VFW32.lib`. 这样做的目的是让连接进程知道除了默认提供的那些标准C++运行时期望之外还有哪些第三方组件也需要考虑进去. ##### 方法二: 确认使用的库版本一致性和兼容性 确保所选库项与其实际应用场合下的参数选项相吻合非常重要。比如当你选择了Debug Build Type的时候就应该加载专门为此准备好的测试专用版别的库而不是Release Mode下预设的那个正式发行版本号相同的对象集合体;反之亦然。 另外还要注意一点关于Runtime Library的选择方面——即是否采用Multithreaded Debug DLL(/MDd), Multithreaded Release DLL (/MD), 或者Static Linkage Against CRT 的区别都会影响到最后能否顺利达成预期效果。 ##### 方法三: 设置合适的搜索路径 有时候仅仅增加单一的目标LIB还不够充分满足需求,因为可能存在多个同名但位于不同位置上的候选实体等待甄别挑选出来加以利用的情形发生。因此有必要进一步扩展全局范围内的探测区域从而提高命中率: 1. 进入 Project Properties 对话框; 2. 定位到 Configuration Properties 下面的 VC++ Directories 分支节点处; 3. 修改Library Files字段内容指向包含待引入模块所在确切地址的一串字符序列列表里边添加上相应的新成员记录下来即可完成整个调整流程工作环节的操作实施全过程描述完毕结束语句标记[^1]. ```cpp // 示例代码展示如何正确引用外部库 #include <windows.h> #include <vfw.h> #pragma comment(lib,"vfw32.lib") int main(){ HWND hwnd = capCreateCaptureWindowA(NULL, WS_CHILD | WS_VISIBLE , 0, 0, 640, 480, NULL, 0); if(hwnd){ MessageBox(NULL,L"Capture Window Created Successfully!",L"Info",MB_OK|MB_ICONINFORMATION); } } ``` ### 注意事项 尽管以上介绍的方法可以帮助大多数开发者克服常见的`LNK2001`难题,但仍需记住每种具体场景都有其独特之处,故而建议仔细阅读官方文档以及查阅社区讨论帖获取更多针对性指导信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值