在VS中添加lib的三种方法
前言
1、每种方法也要复制相应的DLL文件到相应目录,或者设定DLL目录的位置,具体方法为:"Properties" -> "Configuration Properties" -> "Debugging",在"Working Directory"设置dll的路径就可以了
2、无论是设置DLL目录,或者是Lib目录,亦或是头文件的目录,都有release版本和debug版本的区分,每种版本的设置都是独立的,要分别设置。
一、加载方式
方法1: 通过设置工程配置来添加lib库.
A、添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录。
B、添加文件引用的lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录。
C 然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入---附加依赖项:加上lib文件名。
这种方法比较繁琐,且不直观,而且还可能要争对debug版本和release版本作不同的配置,因为我们生成的两个版本的库可能放在不同的目录中的.
方法2: 使用编译语句:
#ifdef _DEBUG
#pragma comment(lib,"..\\debug\\LedCtrlBoard.lib")
#else
#pragma comment(lib,"..\\release\\LedCtrlBoard.lib")
#endif
这种方法直观,方便,且可以按如上直接区分出Debug版本和Release版本的不同目录.当然,通过宏,还可以区分更多版本.
但是在指定目录时,不小心容易出错.
方法3: 直接添加库文件到工程中.
就像你添加.h和.cpp文件一样,把lib文件添加到工程文件列表中去.
VC中,切换到"解决方案视图",--->选中要添加lib的工程-->点击右键-->"添加"-->"现有项"-->选择lib文件-->确定.
就是这么简单,搞定.
这个方法适用于在我的工程的debug版本和Release版本中都使用同一个lib库文件时.这样就省去了你1方法配置环境的繁琐,也省去了方法2种语句的可能性错误发生.
二、动静加载说明
dll的动态加载,又称显式加载,特点有以下几点:
1:灵活,可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存。
2:可以在没有dll时候发现,而不致程序报错。
3:加载程序中有条件才运行的库。
4:热更新,在不停止程序的前提下进行更新。
5:复杂一些,需要显式获得函数地址。
6:dll没有对应的lib文件,此时只能进行动态加载。
7:dll动态加载只需要dll文件就可以了,不需要导入库和头文件。
加载方法:
LoadLibrary
GetProcAddress
FreeLibrary
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "DllLoad.lib")int main()
{HINSTANCE h = LoadLibraryA("DllLoad.dll");typedef int(*FunPtr)(int a, int b);//定义函数指针if (h == NULL){FreeLibrary(h);printf("load lib error\n");}else{FunPtr funPtr = (FunPtr)GetProcAddress(h, "add");if (funPtr != NULL){int result = funPtr(8, 3);printf("8 + 3 =%d\n", result);}else{printf("get process error\n");printf("%d", GetLastError());}FreeLibrary(h);}return 0;
}
dll静态加载,又称隐式加载,需要把库中所有的函数链接到可执行文件中。
1:简单方便;
2:没有dll时,系统报错;
3:加载运行很久的库;
4:dll必需有相应的lib文件;
5:将整个dll库加载到exe中,占用内存较大,但速度较快。
6:dll静态加载需要dll和lib文件以及.h文件。
在调用OpenCV库时,我们就是采用的dll静态加载的方法进行的。
加载方法:
1、确保有a.dll和a.lib,两个文件都有的话可以用静态加载的方式。
2、在.cpp文件中通过#pragma comment(lib, "a.lib") 加载lib,并包含相应的头文件,就可以使用dll中的函数了
Example:
test.h头文件
#ifndef _TEST_H_
#define _TEST_H_#ifdef NEWDLL_EXPORTS
#define MYDLL_API extern "C" __declspec(dllexport)
#else
#define MYDLL_API extern "C" __declspec(dllimport)
#endif
MYDLL_API int add(int x, int y);
#endif
test.c
#include <stdio.h>
#include "test.h"int add(int x, int y)
{return x + y;
}
main.c
#include <stdio.h>
#include "test.h"
#include <Windows.h>//#pragma comment(lib, "DllLoad.lib")int main()
{printf("2 + 3 = %d \n", add(2, 3));return 0;
}
对test.c进行编译后得到DllLoad.lib和DllLoad.dll,这里通过__declspec(dllexport) 将库中的函数导出。在main.c中可以采用两种方法进行动态库的静态加载。
(1)#pragma comment(lib,"DllLoad.lib")
(2)属性-->配置属性-->链接器-->输入-->附加依赖项中添加DllLoad.lib。
注意此处的.lib文件有一个需要注意的地方是:
- 静态库——函数和数据被编译进一个二进制文件(扩展名.lib)。在使用静态库的情况下,在编译连接可执行文件时,连接器从库中复制这些函数和数据并把他们和应用程序的其他模块组合起来创建最终的可执行文件(.exe)文件,当发布产品时,只需要发布这个可执行文件,并不需要发布被使用的静态库。所以采用静态库链接编译的出来的可执行文件一般比动态库链接编译出来的可执行文件要大很多。
- 动态库——在使用动态库时,往往提供两个文件:一个引入库(.lib)文件和一个DLL(.dll)文件。虽然引入库的后缀名也是".lib",但是,动态库的引入库文件和静态库文件有着本质的区别。对一个dll来说,引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据,在使用动态库的情况下,在编译连接和执行文件时,只需要连接该DLL的引入库文件,该DLL中的函数代码和数据并不复制到可执行文件中,直到可执行程序运行时,才去加载所需要的DLL,将该DLL映射到进程的地址空间中,然后访问DLL中导出的函数。这时,在发布产品时,除了发布可执行文件以外,同时还要发布该程序将要调用的动态连接库。
注:
关于lib的静态加载和静态加载:
静态加载(.lib):1.目标函数接口和数据在工程项目编译时,以copy的形式,链入。
2.可执行文件大
动态加载(.lib+.dll):1.库文件(.lib)包含该dll导出的函数和变量的符号名
2..dll文件包含该dll实际的函数和数据
3.项目工程编译时,只需链接该dll的引入库文件,不需copy大量函数和数据
4.执行.exe时,才会加载dll,将dll映射到进程的地址空间中 然后访问dll中导出的函数。
三、lib与dll的区别
1. 使用方式有什么不同?
2. 原因是什么?
其实lib无论怎么样,都会用到。
一种是lib单独使用,另外一种是lib+dll的方式(平时所说的dll的方式)。
1.lib单独使用:
1. LIB包含函数代码本身,不仅包含头文件,还有源码,在编译时直接将代码加入程序当中,称为静态链接库static link library。链接生成的程序可以独立运行。
即lib文件是静态编译出来的,索引和实现都在其中。
2. 同一机器,多个同种程序运行,每个程序都会加载一份代码库。
3. 任何改动,都需要重新编译、链接,这个对大型的程序非常不便,升级也麻烦。有时,在更改数据结构时,需要重新编译整个工程,而非只编译、链接单个lib。
2.lib+dll方式:
1. LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。生成的程序需要dll配合使用。
即lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容。应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中相应函数代码的地址,从而节省了内存资源。
2. 多个程序运行,共享一份代码。节省内存。
3. 当 DLL 中的函数发生更改时,只要函数的参数和返回值没有更改,就不需重新编译或重新链接使用它们的应用程序。
3.使用方式的差别:
1. 静态lib
需要.h和lib。
在生成lib时,相当于cpp编译的obj的集合。链接时,指定lib的位置。
2. 动态lib
实质上是dll的使用方式。
在生成dll时,会生成一个lib,lib里包含的是索引信息。
编译链接时,需要.h,lib。
运行时,需要程序和dll。
有关dll和lib的信息还很多,暂时理解到这个层面吧。
msdn的链接:
http://msdn.microsoft.com/zh-cn/library/dtba4t8b(v=vs.80).aspx
runtime library如何选择?
参考 https://blog.csdn.net/viewcode/article/details/8508211 多线程编程中的操作系统概念
在VS中添加lib的三种方法相关推荐
- mysql添加临时索引_mysql 中添加索引的三种方法
在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...
- mysql 中添加索引的三种方法
在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...
- mysql 中添加索引的三种方法(一)
在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以通过不同的应用场景来进行索引的新建,在此列出三种新建索引的方法 mysql 中添加索引的三种方法 1.1 新建表中添加索 ...
- html 如何给图片打标签,图文详解HTML页面中添加图片的三种方法
在页面布局时,经常需要在页面中插入图片,那你知道如何在HTML中添加图片吗?这篇文章就给大家介绍HTML页面中插入图片的三种方法,感兴趣的朋友可以参考一下,希望对你有所帮助. 方法一.用HTML中的i ...
- c++ 之 在VS中添加lib的4种方法
1.lib的理解 lib是一个二进制文件,与dll类似,供其他程序调用.lib与dll的区别是:dll是运行时需要的,lib是编译时需要的 2.加载lib 分两种方法,第一种适用于当前项目.第二种适用 ...
- 在VS中添加lib的4种方法
1.lib的理解 lib是一个二进制文件,与dll类似,供其他程序调用.lib与dll的区别是:dll是运行时需要的,lib是编译时需要的 2.加载lib 分两种方法,第一种适用于当前项目.第二种适用 ...
- IDEA中添加junit4的三种方法
1.第一种方法 首先创建一个工程,创建好一个测试类,类的名称最好不要取Test,接下来写下一个注解@Test,此时会报错. 报错的原因是创建的工程项目没有导入Junit4依赖,具体查看是在左上角 fi ...
- IDEA中添加junit4的三种方法(详细步骤操作)
今天经过源源不断地踩坑,可算给我搞明白了,下面就介绍我今天学习到的心得. 1.第一种方法 首先创建一个工程,创建好一个测试类,类的名称最好不要取Test,接下来写下一个注解@Test,此时会报错. 报 ...
- windows动态添加lib的三种方法
方法1: 通过设置工程配置来添加lib库. A.添加工程的头文件目录:工程-属性-配置属性-c/c+±–常规-附加包含目录:加上头文件存放目录. B.添加文件引用的lib静态库路径:工程-属性-配置属 ...
最新文章
- Python DB-API 2.0规范
- python3-字典中的一些常用方法
- python导入csv文件中特定列-如何使用标头完整的python导入csv文件,其中第一列为非数字...
- Java对象容器——List
- Centos 6.5 linux 安装nginx
- Window上修改了mysql的配置文件my.ini后重启服务报错:本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止
- div和img之间的缝隙问题
- 基于SSM的校园垃圾分类系统
- idea时间重置插件
- 国际电话号码的区号mysql数据表
- Kiwi Syslog日志服务器的安装及配置使用
- C# 关于winFrom控制网页的自动登录的问题(网页刷屏器的制作原理)
- hdu 4585 Shaolin两种方法(暴力和STL map set)
- 添加zabbix飞信报警
- linux rpm -qip命令,linux rpm命令
- Revit: AR and VR Workflows Revit:AR和VR工作流程 Lynda课程中文字幕
- DateSet和BindingNavigator合作的产物
- 刘韧:和人物共同创作人物故事
- python中sub是什么意思_在Python中split(),sub(),subn()功能?
- IPO是终点,还是起点?
热门文章
- 关于MFC模态对话框dlg.DoModal()返回-1的可能原因
- 摘《阿里巴巴JAVA开发手册》易错题目
- C# GDI画图系列(五) 添加文字和导出图片等附加功能
- PCIe(peripheral component interconnect express)
- Hardware - Serial Peripheral Interface - BIOS
- java入门,eclipse,spring boot… 新建springboot starter, 和 启动mnv srping-boot:run
- 面试之类别数据处理(one-hot、embedding)
- mysql5.155安装教程_git快速入门
- 互联网金融公司在信贷风险管理方面,主要面临哪些挑战
- 界面可视化(四):图像在PyQT5上的显示