关于error LNK20xx的链接错误

引子

使用VS编译C++程序经常会遇到这种情况:编译已经成功,没有报错;但是链接时报错,类似于:“error LNK2001!@#¥#¥@%#……@#¥%&*&¥%¥@#¥”。网上查到的相关文章和我实际遇到不太一样,在这里总结一下我所遇到的链接错误的解决方式。注:这里不明确指明error LNK的错误代码。

一、没有正确的配置XXX.lib

windows编译用到其他的dll库如XXX.dll,不但需要 .h的头文件,而且需要相应的 XXX.lib文件。之前查过说是这个XXX.lib文件是指明了函数的入口地址神马的,但为啥linux下就不需要呢?
回到问题本身,没有正确配置XXX.lib文件有以下几种可能:
a)没有在链接的附加依赖项中写入正确的XXX.lib(或者使用#param 在程序中设定);
b)搜索库文件的路径上XXX.lib不存在(库文件路径没有设置正确);
c)XXX.lib文件有多个版本,而库文件路径上那个版本与你头文件的版本不一致;

二、C++类的函数在头文件中声明了,但是在cpp文件中没有对应的定义。

这种错误比较容易发现。错误中会出现函数名。

三、VS的配置不正确

这个是刚发现,并且昨天折磨了我半个下午。
我们工程的一个solution中包含多个project,而且project之间有依赖关系——某些的project会用到一些基础project生成的lib。
之前的工程在VS2005上,项目依赖很简单,只要在项目点右键->项目依赖项中勾选被依赖的项目即可。
前几天新装电脑,把工程迁移到VS2013上。已有的旧project都没问题。但是新建项目(也是有项目依赖),总是会报error LNK2001或error LNK2019的链接错误。经过仔细对比新旧项目的差别,甚至对.vcxproj文件做diff排查,发现在VS2013中项目依赖要在通用属性->引用中设置。像VS2005那样只在项目依赖项中设置是不行的。具体的发现的过程如下:

  1. 首先排除了前面总结中第二种产生链接错误的可能,链接错误肯定是项目属性页中“连接器”项的某些项配置错了。于是将可以不报错的旧项目和新项目点开逐个页对比。在“命令行”选项卡中发现差别:
    /DYNAMICBASE 项的参数中无链接错误的项目比有错误的多了几行,下图划红线的部分:

    而画红线的部分正是项目所依赖project生成的lib。
  2. 对.vcxproj文件做diff
    正常链接的项目多了以下的配置:
    <ProjectReference Include="..\ENOService\ENOService.vcxproj">
        <Project>{050ad614-2864-4ca2-b878-e16d2b07ed33}</Project>
        <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      </ProjectReference>
      <ProjectReference Include="..\ENOUtils\ENOUtils.vcxproj">
        <Project>{aa57406b-6277-443e-ba0b-8e782ee7ec07}</Project>
        <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      </ProjectReference>

而“ProjectReference Include”部分正是项目所依赖的project。

  1. 从上面的两点可以看出是项目依赖出了问题
    但是项目依赖项已经配置了啊。问题在哪里呢?偶然间手贱,点开了正常链接项目的属性卡中第一项“通用属性”->“引用”:

而链接错误的项目中这一项是空白的。点击“添加新引用”对其进行设置,问题解决!
而且在这里引用了其他项目后,项目右键的“项目依赖项”中的选项是删不掉的。

  1. 总结
    a)问题本质上来讲是没有正确配置lib——没有找到lib文件。
    b)VS2005到VS2013有很多变化,但这个本来在2005中不要配置的项在2013中却要配置了算是被MS坑了?也可以说是我没跟上MS的步伐,out了~
    c)IDE VS 纯文本。IDE在背后帮我们做了很多事。但是我们不了解(我自己水平差,理解不深)。而如果在linux下使用自己写Makefile可已很清楚知道工程所有编译的配置项。甚至当我使用文本编辑器打开了VS的.vcxproj文件,对其中的配置也是一目了然。现在我是越来越倾向于纯文本。IDE在随着版本的变化,哪里修改想要的配置?只能呵呵了。
时间: 2024-10-10 17:26:26

关于error LNK20xx的链接错误的相关文章

模板函数(template function)出现编译链接错误(link error)之解析

总的结论:    将template function 或者 template class的完整定义直接放在.h文件中,然后加到要使用这些template function的.cpp文件中. 1. 现象描述 类似于参考文献[1],当我们以如下方式使用模板函数时,会出现模板函数声明.定义分离带来的链接错误: 1 // File "foo.h" 2 template<typename T> 3 extern void foo(); 1 // File "foo.cpp

mysql链接错误:Lost connection to MySQL server at &#39;reading authorization packet&#39;, system error: 0

在远程连接mysql的时候,连接不上,出现如下报错:Lost connection to MySQL server at 'reading authorization packet', system error: 0原因分析:mysql开启了DNS的反向解析功能,这样mysql对连接的客户端会进行DNS主机名查找.mysql处理客户端解析过程:1)当mysql的client连过来的时候,服务器会主动去查client的域名.2)首先查找 /etc/hosts 文件,搜索域名和IP的对应关系.3)如

Duplicate Symbol链接错误的原因总结和解决方法[转]

from:http://www.cocoachina.com/bbs/read.php?tid=177492 duplicate symbol是一种常见的链接错误,不像编译错误那样可以直接定位到问题的所在.但是经过一段时间的总结,发现这种错误总是有一些规律可以找的.例如,我们有如下的最简单的两个类代码: //  ClassA.h#import <Foundation/Foundation.h>@interface ClassA : NSObject@end //  ClassA.m#impor

Ogre1.6.5 编译链接错误之FreeImage

这两天想重新学习下ogre,但是在vs2010上编译1.6.5的版本上遇到链接失败的问题,耗了不少时间这里记一下. 主要是一些重定义报错. >msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: class std::basic_ostream<char,struct std::char_traits<char> > & __thiscall std::basic_ostream<char,stru

Xerces链接错误原因之/Zc:wchar_t-设置不一致

今天程序需要使用Xerces作为xml文件的解析与序列化工具,使用的是Xerces2.7.0版本.具体编译教程如下: 成功编译出了Xerces.dll和Xerces.lib.但是在链接到主工程的时候,总是链接失败.报错如下 error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: static wchar_t const * const xercesc_2_7::XMLUni::fgDOMWRTFormatPrettyPrint"

Treat wchar_t as built-in type不一致导致的链接错误

今天用VS2013新建了一个工程,生成时出现很多怪异的链接错误,比如: error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class MTString __cdecl MTString::fromWCharArray(wchar_t const *,int)"([email protected]@@[email protected][email protected]) refe

VC中链接错误,提示string重定义

VC链接错误,说是string已经有了实现了,只要 rebuild 一下好了. Linking...LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specificationmsvcprtd.lib(MSVCP71D.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<

VC++的链接错误LNK2005 已经在*.obj中定义

LNK2005错误--重复定义错误 形成的原因: 1. 重复定义全局变量.可能存在两种情况: A. 对于一些初学编程的程序员,有时候会以为需要使用全局变量的地方就可以使用定义申明一下.其实这是错误的,全局变量是针对整个工程的.正确的应该是在一个CPP文件中定义如下:int g_Test;那么在使用的CPP文件中就应该使用:extern int g_Test即可,如果还是使用int g_Test,那么就会产生LNK2005错误,一般错误错误信息类似:AAA.obj error LNK2005 in

C++常见gcc编译链接错误解决方法

除非明确说明,本文内容仅针对x86/x86_64的Linux开发环境,有朋友说baidu不到,开个贴记录一下(加粗字体是关键词): 用“-Wl,-Bstatic”指定链接静态库,使用“-Wl,-Bdynamic”指定链接共享库,使用示例:-Wl,-Bstatic -lmysqlclient_r -lssl -lcrypto -Wl,-Bdynamic -lrt -Wl,-Bdynamic -pthread -Wl,-Bstatic -lgtest("-Wl"表示是传递给链接器ld的参数