分享

error2001

 yunwang 2010-03-29

很讨厌的error link2001之一二三

学习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错误虽然比较困难,但是只要注意到了上述问题,还是能  
  够避免和予以解决的。 

再:

error LNK2001: unresolved external symbol _main解决办法
2007年04月07日 星期六 11:39
作者: liuhuinwpu 发表日期: 2006-05-28 复制链接 收藏
解决外部符号错误:_main,_WinMain@16,__beginthreadex )
在创建MFC项目时, 不使用MFC AppWizard向导, 如果没有设置好项目参数,就会在编译时产生很多连接错误, 如error LNK2001错误, 典型的错误提示有:  
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main  
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16  
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16  
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex  
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex n  

1. Windows子系统设置错误, 提示:  
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main  

Windows项目要使用Windows子系统, 而不是Console, 可以这样设置:  

[Project] --> [Settings] --> 选择"Link"属性页,
在Project Options中将/subsystem:console改成/subsystem:windows   

2. Console子系统设置错误, 提示:
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16

控制台项目要使用Console子系统, 而不是Windows, 设置:  

[Project] --> [Settings] --> 选择"Link"属性页,  
在Project Options中将/subsystem:windows改成/subsystem:console  

3. 程序入口设置错误, 提示:  
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16

通常, MFC项目的程序入口函数是WinMain, 如果编译项目的Unicode版本, 程序入口必须改为wWinMainCRTStartup, 所以需要重新设置程序入口:

[Project] --> [Settings] --> 选择"Link"属性页,
在Category中选择Output,
再在Entry-point symbol中填入wWinMainCRTStartup, 即可

4. 线程运行时库设置错误, 提示: @: kAF n
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex

这是因为MFC要使用多线程时库, 需要更改设置:

[Project] --> [Settings] --> 选择"C/C++"属性页, ')
在Category中选择Code Generation,
再在Use run-time library中选择Debug Multithreaded或者multithreaded
咸鱼游侠(75374355) 12:11:11
其中,
Single-Threaded                    单线程静态链接库(release版本)
Multithreaded                      多线程静态链接库(release版本)
multithreaded DLL                  多线程动态链接库(release版本)  
Debug Single-Threaded              单线程静态链接库(debug版本)
Debug Multithreaded                多线程静态链接库(debug版本)
Debug Multithreaded DLL            多线程动态链接库(debug版本) 单线程: 不需要多线程调用时, 多用在DOS环境下
多线程: 可以并发运行
静态库: 直接将库与程序Link, 可以脱离MFC库运行
动态库: 需要相应的DLL动态库, 程序才能运行
release版本: 正式发布时使用
debug版本: 调试阶段使用  

From MSDN:

Visual C++ Concepts: Building a C/C++ Program
Linker Tools Error LNK2001

unresolved external symbol "symbol"

Code references something (such as a function, variable, or label) that the linker can't find in the libraries and object files.

Possible causes

  • What the code asks for doesn't exist (the symbol is spelled incorrectly or uses the wrong case, for example).
  • 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).

This error message is followed by fatal error LNK1120.

Specific causes

Coding Problems

  • If the LNK2001 diagnostic text reports that __check_commonlanguageruntime_version is an unresolved external symbol, see LNK2019 for information on how to resolve.
  • The definition of member template is outside the class. Visual C++ has a limitation in which member templates must be fully defined within the enclosing class. See KB article Q239436 for more information about LNK2001 and member templates.
  • 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.
  • A project that uses function inlining yet defines the functions in a .cpp file rather than in the header file can cause LNK2001.
  • Calling a C function from a C++ program without using extern "C" (which causes the compiler to use the C naming convention) can cause LNK2001. Compiler options /Tp and /Tc cause the compiler to compile files as C or C++, respectively, regardless of the filename extension. These options can cause function names different from what you expect.
  • Attempting to reference functions or data that don't have external linkage can cause LNK2001. In C++, inline functions and const data have internal linkage unless explicitly specified as extern.
  • A missing function body or variable can cause LNK2001. With just a function prototype or extern declaration the compiler can continue without error, but the linker cannot resolve a call to an address or reference to a variable because there is no function code or variable space reserved.
  • Calling a function with parameter types that do not match those in the function declaration can cause LNK2001. Name decoration incorporates the parameters of a function into the final decorated function name.
  • Incorrectly included prototypes, which cause the compiler to expect a function body that is not provided can cause LNK2001. If you have both a class and non-class implementation of a function F, beware of C++ scope-resolution rules.
  • When using C++, including a function prototype in a class definition and failing to include the implementation of the function for that class can cause LNK2001.
  • Attempting to call a pure virtual function from the constructor or destructor of an abstract base class can cause LNK2001. A pure virtual function has no base class implementation.
  • Trying to access a static variable from outside the file in which it is declared can cause LNK2001. Functions declared with the static modifier by definition have file scope. Static variables have the same limitation.
  • Trying to use a variable declared within a function (a local variable) outside the scope of that function can cause LNK2001.
  • Trying to use a global constant in C++ in multiple files can cause LNK2001. In C++, unlike C, global constants have static linkage. To get around this limitation, you can include the const initializations in a header file and include that header in your .cpp files, or you can make the variable non-constant and use a constant reference to access it.
  • When building a Release version of an ATL project, indicates that CRT startup code is required. To fix, do one of the following,
    • Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT startup code to be included. See General Configuration Settings Property Page for more information.
    • If possible, remove calls to CRT functions that require CRT startup code. Instead, use their Win32 equivalents. For example, use lstrcmp instead of strcmp. Known functions that require CRT startup code are some of the string and floating point functions.

Compiling and Linking Problems

  • The project is missing a reference to a library (.LIB) or object (.OBJ) file. See .lib Files as Linker Input for more information.
  • Using /NOD if the names of the run-time and MFC libraries are included in the object file module can cause LNK2001. If you use the /NOD (/NODEFAULTLIB) option, these libraries will not be linked into the project unless you have explicitly included them.
  • If you are using Unicode and MFC, you will get an unresolved external on _WinMain@16 if you don't create an entrypoint to wWinMainCRTStartup; use the /ENTRY. See Unicode Programming Summary.

    See the following Knowledge Base articles, located in the MSDN Library, for more information. In the MSDN Library, click the Search tab, paste the article number or article title into the text box, and then click List Topics. If you search on the article number, make sure the Search titles only option is clear.

    • 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"
    • Q291952    "PRB: Link Error LNK2001: Unresolved External Symbol _main"
  • Linking code compiled with /MT with the library LIBC.lib causes LNK2001 on _beginthread, _beginthreadex, _endthread, and _endthreadex.
  • Linking code requiring the multithreaded libraries (any MFC code or code compiled with /MT) causes LNK2001 on _beginthread, _beginthreadex, _endthread, and _endthreadex. See the following Knowledge Base article for more information:
    • Q126646 "PRB: Error Msg: LNK2001 on __beginthreadex and __endthreadex"
    • Q128641 "INFO: /Mx Compiler Options and the LIBC, LIBCMT, MSVCRT Libs"
    • Q166504 "PRB: MFC and CRT Must Match in debug/release and static/dynamic"
  • 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. You may want to change the order of the directories in the search path, or changing them to point to the current version.

    The Tools | Options | Projects | VC++ Directories dialog, under the Library files selection, allows you to change the search order. The Linker folder in the project's Property Pages dialog box may also contain paths that could be out of date.

    This problem may appear when a new SDK is installed (perhaps to a different location), and the search order is not updated to point to the new location. Normally, you should put the path to new SDKs' include and lib directories in front of the default Visual C++ location. Also, a project containing embedded paths may still point to old paths that are valid, but out of date for new functionality added by the new version that is installed to a different location.

  • 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.
  • The project is created as a managed DLL that contains Microsoft intermediate language code that does not link to native C/C++ libraries such as the CRT, ATL, or MFC, and you add code from a native C/C++ library that uses static variables. To fix, you must convert the project to mixed mode. For more information, see Converting Managed Extensions for C++ Projects from Pure Intermediate Language to Mixed Mode.

     

     

     

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 the EXPORTS 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 C++ decorated names (.def files do not take decorated names)

Interpreting the Output

When a symbol is unresolved, you can get information about the function by the following guidelines:

On x86 platforms, the calling convention decoration for names compiled in C, or for extern "C" names in C++, is:

__cdecl
Function has an underscore (_) prefix.
__stdcall
Function has an underscore (_) prefix and an @ suffix followed by the dword aligned size of parameters on the stack.
__fastcall
Function has an @ prefix and an @ suffix followed by the dword aligned size of parameters on the stack.

Use undname.exe to get the undecorated form of a decorated name.

For more information on some of the causes listed above, see:

 

 

 

 

 

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多