Additinal Dependencies和#pragma comment(lib,"*.lib")的分析
Additinal Dependencies和#pragma comment(lib,"*.lib")都是针对.lib文件的。
而.lib文件其实有两种。
一种是与DLL相关的,描述DLL中的函数入口地址等的,在这里两种方法作用一样。
一种是静态链接库,就是将静态库工程当前所有目标文件编译成一个二进制文件(通常是以.lib为扩展名)。Additinal Dependencies和#pragma comment(lib,"*.lib")在这静态库这里会体现出重大的不同。
假如我们有4个工程,静态库工程A,B,C和EXE工程D,B依赖A,C依赖B,D依赖C,D依赖于C。
#pragma comment(lib,"*.lib")
其作用是放置1个库的链接搜索记录到目标文件中,这个搜索记录排在默认搜索记录之后。可以在一个目标文件中放置多个搜索记录,其顺序依据于源码中添加的顺序。因为这行代码的作用只是指明链接时去相应的lib文件中查找相应函数的实现代码,只是一个记录指明的作用,并没有链接的作用。
lib工程并没有链接过程,只有编译过程。只有在生成DLL/EXE时,才会有链接过程的产生,将会将所有目标链接在一起。
因为没有链接过程,所以在编译B,C, D工程时并不需要指明其依赖的静态库(lib),只需要#include相应的头文件即可以编译生成lib文件。
那么在链接生成DLL/EXE时,则需要指明链接搜索记录。
可以在工程D中指明所有需要链接搜索的lib文件。
#pragma comment(lib,"A.lib")
#pragma comment(lib,"B.lib")
#pragma comment(lib,"C.lib")
这个时候才会真正完成链接过程,会检查函数是否定义了,是否重复定义等链接错误。
因为D表面看只依赖C,所以指明B.lib, C.lib感觉不太直观,更直观的可能是用到哪个lib添加哪个:
工程B中添加#pragma comment(lib,"A.lib")
工程C中添加#pragma comment(lib,"B.lib")
工程D中添加#pragma comment(lib,"C.lib")
Project Property->Additinal Dependencies->*.lib
这种方式附加lib文件,看起来效果与上面的方式一样,其实工作原理是不一样的,认识不清,容易产生一些问题。
AdditinalDependencies->*.lib分两种情况:
1、静态库工程中,Configuration Properties->Librarian->General->Additinal Dependencies
其作用是附加指定的lib文件至当前工程,并编译生成至当前的lib文件中。这种行为有点类似链接,但不是链接,只是将将指定lib文件合并到新的lib文件中来。
如果单独编译A, B, C, 它们均生成50K大小的lib文件。
工程B中Additinal Dependencies->A.lib
工程C中Additinal Dependencies->B.lib
那么B.lib将会是100K,C.lib将会是150K。可以看到是直接合并进来的。
但如果是如下设置:
工程B中Additinal Dependencies->A.lib
工程C中Additinal Dependencies->A.lib;B.lib
那么B.lib将会是100K,C.lib将会是200K。可以看到C.lib直接将A.lib,B.lib直接合并进来了,相当于合并了两份A.lib。这样会导致重复合并,VS编译器会提出warning LNK4006,already defined in *.obj;second definition ignored。虽然报出来的是一个链接警告,但其实并不是链接过程的。因为这样的情况很多,所以会出现非常多这类警告。MSDN对这类警告的有个相差描述:You can get this warning if you try to merge twoimport libs into one.就是指我们上面合并两个lib文件。
解决方法也分两种:
A、不合并多个lib文件成1个lib文件,则我们不需要在静态库工程中设置Additinal Dependencie。可以在DLL/EXE中通过
#pragma comment(lib,"*.lib")一次全部指明lib搜索记录,也可以在DLL/EXE工程中通过Additinal Dependencie一次附加所有涉及到的lib。如果想更直观点,用到哪个lib指明哪个,即分别在相应的lib工程里用#pragma comment(lib,"*.lib")指明相应的lib文件即可。
B、合并多个lib文件,工程B Additinal Dependencies->A.lib, 工程C Additinal Dependencies->B.lib即可。
2、DLL/EXE工程中,Configuration Properties->Linker->Input->AdditinalDependencies
可以看出,这里是在链接器下面的一个设置,也说明这里的附加是为链接完成的,即指明链接lib搜索记录,作用与#pragma comment(lib,"*.lib")一样,只不过在DLL/EXE中会产生链接过程。静态库中出现的重复重复定义、定义未实现均不会报错,但是链接过程中会检查这类错误,所以很多静态库中的错误会在DLL/EXE工程的链接结果中报出来。
Additinal Dependencies和#pragma comment(lib,"*.lib")的分析的更多相关文章
- #pragma comment使用
编程经常碰到,理解的总不是很透彻,在这里查阅资料总结一下! 在编写程序的时候,我们常用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作. #pragma once : 这是一个 ...
- pragma comment的使用
该宏放置一个注释到对象文件或者可执行文件. #pragma comment( comment-type [,"commentstring"] ) comment-type是一个预定 ...
- pragma comment的使用 pragma预处理指令详解
pragma comment的使用 pragma预处理指令详解 #pragma comment( comment-type [,"commentstring"] ) 该宏放置一 ...
- pragma comment的使用(转)
#pragma 的使用 尽管 C 和 C++ 都已经有标准,但是几乎每个编译器 (广义,包含连接器等) 扩展一些 C/C++ 关键字. 合理地应用这些关键字,有时候能使我们的工作非常方便.下面随便说说 ...
- #pragma comment 的使用方法
转发:https://blog.csdn.net/liruda/article/details/2230617 #pragma comment ( lib,"wpcap.lib" ...
- lib包含# #pragma comment
#pragma comment(lib,"d2d1.lib")#pragma comment(lib,"dwrite.lib")#pragma comment( ...
- 在头文件#pragma comment(lib,"glaux.lib");编译器提示waring C4081: 应输入“newline“
在头文件#pragma comment(lib,"glaux.lib");编译器提示waring C4081: 应输入“newline“ #行不能加分号的
- pragma comment
pragma指令简介 在编写程序的时候,我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作. 下面介绍了一下该指令的一些常用参数,希望对大家有所帮助! 一. mess ...
- #include 和 #pragma comment 的相对路径起点
#include 是以当前文件所在路径为当前目录 #pragma comment 是以当前工程所在路径为当前目录 #include "../../../../ThirdParty/Inclu ...
随机推荐
- 批量复制windows文件夹下所有文件名
第一步,打开文件夹 第二步,在该文件夹下新建一个txt文件,然后将“.txt”后缀名修改为“.bat” txt文件内容“DIR *.* /B >LIST.TXT” 第三步,双击“.bat”,直接 ...
- 20155204 2016-2017-2 《Java程序设计》第10周学习总结
20155204 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 1.计算机网络概述 路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控 ...
- 安装虚拟机与Linux的学习
#虚拟机 在安装虚拟机之前,我先上网查了一些关于虚拟机的知识. 虚拟机,即Virtual Machine,在计算机科学中的体系结构裏,是指一种特殊的软件,他可以在计算机平台和终端用户之间创建一种环境, ...
- 2016-2017-2 20155322 实验三 敏捷开发与XP实践
2016-2017-2 20155322 实验三 敏捷开发与XP实践 实验内容 XP基础 XP核心实践 相关工具 实验知识点 敏捷开发(Agile Development)是一种以人为核心.迭代.循序 ...
- odoo学习之:在tree view中显示部分数据domain的使用
只要在window.action中他添加相应东domain即可,如: <!-- 树型列表 --> <record model="ir.actions.act_window& ...
- 打豪车应用:uber详细攻略(附100元优步uber优惠码、uber优惠券、优步优惠码、优步优惠券)
在嘀嘀打车和快的打车交战热闹的时候,美国的打车应用uber进入中国.与在美国以个人司机注册做 Uber 司机为主的模式不同,Uber 在中国采用与租车公司合作.由租车公司提供车辆和司机的模式,同时中文 ...
- python 逆波兰式
逆波兰式,也叫后缀表达式 技巧:为简化代码,引入一个不存在的运算符#,优先级最低.置于堆栈底部 class Stack(object): '''堆栈''' def __init__(self): se ...
- iframe ie低版本 横向滚动条的解决办法
吐槽下百度,在百度搜这个问题都是渣渣,谷歌直接就出来了,记录一下 设置Frame时,有一属性是scrolling="yes/no/auto",IE6的mozilla都支持,或许对a ...
- 借助全新 MATLAB® 适配器代码示例读取英特尔® 实感™ 摄像头数据流
下载源代码请访问原文地址:借助全新 MATLAB® 适配器代码示例读取英特尔® 实感™ 摄像头数据流 简介 该可下载代码示例简要介绍了如何使用英特尔® 实感™ SDK 和 MATLAB 的图像采集工具 ...
- sublime3配置java开发环境
链接:http://www.jianshu.com/p/48a524a4f63c 或者:http://www.jianshu.com/p/9d167c4c4feb 侵权删!