error LNK2001: unresolved external symbol这样解决

转自:http://topic.csdn.net/t/20021021/10/1111007.html

 

Visual   C++   概念:生成   C/C++   程序        
   
  链接器工具错误   LNK2001无法解析的外部符号“symbol”  
   
  代码引用了链接器无法在库和对象文件中找到的内容(如函数、变量或标签)。  
   
  可能的原因    
   
  代码请求的内容不存在(例如,符号拼写错误或使用错误的大小写)。    
  代码请求的内容错误(使用的是混合版本的库,一些库来自产品的一个版本,而其他则来自另一个版本)。    
  该错误信息之后为致命错误   LNK1120。  
   
  具体原因  
   
  代码问题    
   
  成员模板的定义超出了类的范围。Visual   C++   的一个限制是,成员模板的定义必须完全位于封闭类内。有关   LNK2001   和成员模板的更多信息,请参阅知识库文章   Q239436。    
  代码或模块定义   (.def)   文件中的大小写不匹配会导致   LNK2001。例如,当在一个   C++   源文件中将一个变量命名为   var1,并试图在另一个源文件中以   VAR1   访问该变量时。    
  如果项目使用函数内联,但在   .cpp   文件而非头文件中定义函数,则会导致   LNK2001。    
  从   C++   程序调用   C   函数但不使用   extern   "C"(这导致编译器使用   C   命名约定)会导致   LNK2001。编译器选项   /Tp   和   /Tc   使编译器将文件分别编译为   C   或   C++,与文件扩展名无关。这些选项会导致函数名与您所期望的名称不同。    
  试图引用没有外部链接的函数或数据会导致   LNK2001。在   C++   中,内联函数和   const   数据具有内部链接,除非被显式指定为   extern。    
  缺少函数主体或变量会导致   LNK2001。如果只有函数原型或   extern   声明,编译器继续运行而不会出现任何错误,但由于没有保留函数代码或变量空间,链接器将无法解析地址调用或变量引用。    
  调用参数类型与函数声明中的参数类型不匹配的函数会导致   LNK2001。名称修饰将函数参数合并到最终的修饰函数名中。    
  错误包含的原型导致编译器需要没有提供的函数体,这样会导致   LNK2001。如果同时具有函数   F   的类实现和非类实现,请注意   C++   范围解析规则。    
  在使用   C++   时,将函数原型包含在类定义中但未能包含实现(该类的此函数的实现)会导致   LNK2001。    
  试图从抽象基类的构造函数或析构函数调用纯虚函数会导致   LNK2001。纯虚函数没有基类实现。    
  试图从包含静态变量声明的文件外部访问该静态变量会导致   LNK2001。根据定义,用   Static   修饰符声明的函数具有文件范围。静态变量具有相同的限制。    
  试图在函数范围外使用用该函数声明的变量(局部变量)会导致   LNK2001。    
  试图在多个文件中使用   C++   全局常数会导致   LNK2001。与   C   不同,在   C++   中全局常数具有   static   链接。若要避免此限制,可以将   const   初始化包括在头文件中,并将此头包括在   .cpp   文件中,也可以使变量成为非常数,然后使用常数引用访问它。    
  在生成   ATL   项目的发布版本时,指示需要   CRT   启动代码。若要修复,请执行下列操作之一:    
  将   _ATL_MIN_CRT   从预处理器定义列表中移除,以允许包括   CRT   启动代码。有关更多信息,请参阅常规配置设置属性页。    
  如果可能,移除对需要   CRT   启动代码的   CRT   函数的调用,而是使用它们的   Win32   等效函数。例如,使用   lstrcmp   取代   strcmp。需要   CRT   启动代码的已知函数是一些字符串和浮点函数。    
  编译和链接问题    
   
  当运行时库和   MFC   库的名称包含在对象文件模块中时使用   /NOD   会导致   LNK2001。如果使用   /NOD   (/NODEFAULTLIB)   选项,这些库将不会链接到项目中,除非显式包含了它们。    
  使用   Unicode   和   MFC   时,如果没有创建   wWinMainCRTStartup   的入口点,将在   _WinMain@16   上得到无法解析的外部对象;请使用   /ENTRY。请参阅   Unicode   编程摘要。    
  有关更多信息,请参阅下列位于   MSDN   库中的知识库文章。在   MSDN   库中,单击“搜索”选项卡,将文章编号或文章标题粘贴在文本框中,然后单击“列出主题”。如果按文章编号搜索,确保清除“仅搜索标题”选项。    
   
  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”    
  将用   /MT   编译的代码与库   LIBC.lib   链接会在   _beginthread、_beginthreadex、_endthread   和   _endthreadex   上导致   LNK2001。    
  链接需要多线程库的代码(任何   MFC   代码或用   /MT   编译的代码)会在_beginthread、_beginthreadex、_endthread   和   _endthreadex   上导致   LNK2001。有关更多信息,请参阅下列知识库文章:    
  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”    
  在用   /MD   进行编译时,因为所有的运行库现在都存放在   DLL   中,所以源中的“func”引用在对象中变为“__imp__func”引用。如果试图与静态库   LIBC.lib   或   LIBCMT.lib   链接,则将在   __imp__func   上得到   LNK2001。当不用   /MD   进行编译时,如果试图与   MSVCxx.lib   链接,则并非总是得到   LNK2001,但可能会有其他问题。    
  将用显式或隐式   /ML   编译的代码链接到   LIBCMT.lib   时将在   _errno   上导致   LNK2001。    
  在生成应用程序的调试版本时与发布模式库链接会导致   LNK2001。同样,使用   /Mxd   选项(/MLd、/MTd   或   /MDd)并/或定义   _DEBUG,然后与发布库链接将带来潜在的无法解析的外部对象(以及其他问题)。将发布模式生成与调试库链接同样会导致类似问题。    
  将   Microsoft   库版本和编译器产品版本混合可能会有问题。新编译器版本的库可能包含早期版本的库中没有的新符号。可能需要更改搜索路径中的目录顺序,或将它们更改为指向当前版本。    
  在“工具”|“选项”|“项目”|“VC++   目录”对话框中,“库文件”选项允许更改搜索顺序。项目的“属性页”对话框中的“链接器”文件夹可能也包含可能已过期的路径。    
   
  当安装了新的   SDK(可能在不同的位置),但没有将搜索顺序更新为指向新位置时,可能会出现此问题。通常情况下,应将新   SDK   的   include   目录和   lib   目录的路径放在默认   Visual   C++   位置的前面。另外,包含嵌入路径的项目可能仍然指向旧路径,这些路径是有效的,但对于安装到不同位置的新版本所添加的新功能已过期。    
   
  编译器供应商之间、甚至同一编译器的不同版本之间当前没有   C++   命名标准。因此,链接用其他编译器编译的对象文件可能无法生成相同的命名方案,从而导致错误   LNK2001。    
  在不同模块上混合内联和非内联编译选项会导致   LNK2001。如果创建   C++   库时打开了函数内联(/Ob1   或   /Ob2),但描述函数的相应头文件的内联是关闭的(没有   inline   关键字),将发生此错误。若要防止此问题,请在要包含到其他文件中的头文件中用   inline   定义内联函数。    
  如果使用   #pragma   inline_depth   编译器指令,请确保具有设置为   2   或更大的值,并确保使用   /Ob1   或   /Ob2   编译器选项。    
  在创建纯资源   DLL   时省略   LINK   选项   /NOENTRY   将导致   LNK2001。    
  使用不正确的   /SUBSYSTEM   或   /ENTRY   设置会导致   LNK2001。例如,如果编写基于字符的应用程序(控制台应用程序)并指定   /SUBSYSTEM:WINDOWS,您将得到无法解析的   WinMain   外部对象。有关这些选项和入口点的更多信息,请参见   /SUBSYSTEM   和   /ENTRY   链接器选项。    
  导出问题    
   
  当将应用程序从   16   位移植到   32   位时,会发生   LNK2001。当前的   32   位模块定义   (.def)   文件语法要求   __cdecl、__stdcall   和   __fastcall   函数列在   EXPORTS   节中,并且不带下划线(不修饰)。这不同于   16   位语法,这些函数在   16   位语法中列出时必须带下划线(修饰)。有关更多信息,请参阅模块定义文件   EXPORTS   节的说明。    
  在   .def   文件中列出但未找到的任何导出将导致   LNK2001。这可能是因为导出不存在、拼写错误或使用了   C++   修饰名(.def   文件不采用修饰名)。    
  解释输出  
   
  如果符号无法解析,通过下列指南可获得有关函数的信息:  
   
  在   x86   平台上,用   C   编译的名称或   C++   中的   extern   "C"   名称的调用约定修饰是:    
   
  __cdecl    
  函数具有下划线   (_)   前缀。    
  __stdcall    
  函数具有下划线   (_)   前缀和   @   后缀,后跟堆栈上参数的双倍字长对齐大小。    
  __fastcall    
  函数具有   @   前缀和   @   后缀,后跟堆栈上参数的双倍字长对齐大小。    
  使用   undname.exe   获取修饰名的未修饰格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值