区别
.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。
附加依赖项添加的是.lib而不是.dll,若生成了DLL,则肯定也生成了LIB文件。
.h .lib .dll三者的关系:
H文件的作用:声明函数接口
DLL文件作用:函数可执行代码
LIB文件作用:当我们在自己的程序中引用了一个H文件里的函数,链接器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用了。它告诉链接器调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,这也就是为什么需要附加依赖项.LIB文件,它起到桥梁的作用。
如果是生成静态库文件,则没有DLL,只有lib,这时函数可执行代码部分也在lib文件中。
目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。
静态编译的lib文件的好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。
在动态库的情况下,有两个文件,而一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。
在Vs中加载LIB文件的几种方法:
①LIB文件直接加入到工程文件列表中
在Vs中打开solution explorer一页,选中headFile,单击鼠标右键,然后选中Add-->Exisiting Item 菜单,在弹出的文件对话框中选中要加入DLL的LIB文件即可。
②通过程序代码的方式
加入预编译指令#pragma comment (lib,"*.lib"),这种方法优点是可以利用条件预编译指令链接不同版本的LIB文件。因为,在Debug方式下,产生的LIB文件是Debug版本,如Regd.lib;在Release方式下,产生的LIB文件是Release版本,如Regr.lib。
当应用程序对DLL的LIB文件加载后,还需要把DLL对应的头文件(*.h)包含到其中,在这个头文件中给出了DLL中定义的函数原型,然后声明。
静态库编译之后会生成对应的.lib文件,在工程A中使用时,配置A的属性,首先要附加的include 路径里,添加.lib库对应的头文件所在的路径。然后在链接器设置里,附加的库路径里添加.lib库所在的路径,然后在链接器的输入里,添加.lib库的名字即可。
动态链接库的创建的不同之处在于,需要在所有函数的声明前边加上 __declspec(dllexport) ,动态链接库的创建也会产生.lib文件,这个文件比较小,只有几K ,叫导入库,只是一些符号信息,提供给编译器索引。总之,.lib都是编译时用到。
加入动态链接库,编译通过之后,要想运行,需要将动态链接库.dll 文件拷贝到A工程目录下边。
另外,debug 产生的动态链接库和静态链接库,只能给A工程在debug 状态下使用。也就是说,A工程在release状态下用的 静态链接库和动态链接库,需要提供对应的release版。
静态库创建和使用
1 创建一个静态库
文件-新建项目-win32项目
选择静态库
完成
在你要添加的头文件中添加头文件
源文件
引文这是一个静态库,所以不能生成程序
这个时候你发现在你的Debug目录下面生成了一个静态库
这样就生成了一个静态库
2 使用静态库
文件-新建项目-win32项目
确定
将上一个项目的头文件拿过来,以及生成的静态库文件
添加源文件myTestStaticLib.cpp, 添加内容
运行
程序实现了静态库的功能
一、VS2013动态库文件的创建
1、新建项目,win32,win32项目,输入项目名称,例如MakeDll。
2、”确定“——”下一步“,选择”DLL“选项,再点”完成“:
3、菜单栏选择”项目“——>”添加新项“,来创建头文件MakeDll.h。
在MakeDll.h中输入以下例子代码:
1 #ifdef DLL_API//如果已经定义就什么都不做 2 //nothing to do 3 #else //否则定义DLL_API 4 #define DLL_API __declspec(dllexport) //_declspec(dllexport):导出标志 5 #endif 6 #include <iostream> 7 using namespace std; 8 DLL_API int add(int a, int b);//导出单独的函数 9 class DLL_API Point //导出类,其自身所有函数都将被导出,可单独对某些类函数导出 10 { 11 private: 12 float x, y; 13 public: 14 Point(); 15 void SetPoint(float a, float b); 16 void DisPlay(); 17 };
4、创建cpp文件:MakeDll.cpp。
在MakeDll.cpp中输入以下例子代码:
1 #include "MakeDll.h" 2 3 int add(int a, int b) 4 { 5 return a + b; 6 } 7 8 Point::Point() 9 { 10 x = 0.0f; 11 y = 0.0f; 12 } 13 14 void Point::SetPoint(float a, float b) 15 { 16 x = a; 17 y = b; 18 } 19 void Point::DisPlay() 20 { 21 cout << "x=" << x << endl; 22 cout << "y=" << y << endl; 23 }
5、菜单栏选择”生成——>生成解决方案“。
此时在MakeDll项目所在目录下的Debug目录下的文件有MakeDll.dll和MakeDll.lib了。生成动态链接库文件OK。
使用刚才创建的动态库
1、新建项目——win32控制台应用程序,命名为UseDll,并创建一个lib文件,将MakeDll.lib引导库放进去,
并将MakeDll.dll放进debug下,编译器会自动搜素到这个文件,当然可以放在系统目录下。
2、告诉编译器头文件MakeDll.h的位置(见包含目录)、引导库位置(见库目录)及其名字(见附加依赖项)。注意,以下是添加后的显示结果。
图.包含目录的设置
图.库目录的设置
图.附加依赖项的设置
3、最后,动态库的测试程序如下,测试程序需要引用头文件:
1 #include <iostream> 2 #include "MakeDll.h" 3 using namespace std; 4 5 int main() 6 { 7 int a = 10; 8 int b = 2; 9 int c = add(a, b); 10 cout << c << endl; 11 Point p1, p2; 12 p2.SetPoint(5.6f, 7.8f); 13 p1.DisPlay(); 14 p2.DisPlay(); 15 getchar(); 16 return 0; 17 }
运行结果:
至此测试成功!