偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件。然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DLL或者LIB导入到我们的编程中,那么这些lib,DLL到底是什么呢?下面,偶就细细道来。

首先,偶们说第一个静态链接库(Static Libary

偶们用VS2005做一个静态链接库先

打开VS2005,新建à项目(staticCai)àWin32控制台应用程序

新建static_lib.h 和static_lib.cpp 两个文件,这两个文件的内容如下:

static_lib.h

int add(int x,int y);

int substract(int x , int y);

static_lib.cpp

 

#include "static_lib.h"

int add(int x,int y)

{

return x + y;

}

int substract(int x,int y)

{

return x - y;

}

然后编译,生成解决方案,好,这样不出意外会在debug文件夹(与staticCai并列)下生成一个staticCai.lib文件,好了,这个就是我们做好的静态链接库。下面,我们看看怎么用这个静态链接库。我们再新建一个win32控制台程序,新建main.cpp内容如下:

#include <iostream>

#include "static_lib.h"

#pragma comment(lib, "static.lib")

using namespace std ;

int main()

{

cout << add(3 ,4) << endl ;

cout << substract(5 , 3) << endl ;

return 0 ;

}

并且将staticCai.lib和static_lib.h这两个文件拷贝到与main.cpp并列的文件夹下。然后,我们编译,链接,执行程序,就会出结果了

#pragma comment(lib, "static.lib")这句和我们在 项目à属性à连接器à添加依赖项 的效果是一样的。至此,怎么做静态链接库以及怎么用静态链接库就搞定了。现在,我们把刚刚拷贝过来的staticCai.lib给删了,我们发现,程序照样执行,但是不能再链接了。所以,我们得出这样的结论:我们再链接的时候需要静态链接库,一旦链接成功,生成了可执行文件,那么,静态链接库就不再需要了。

其次,偶们说第二个动态链接库(dynamic link Libary

同样,我们来做一个动态链接库,和上面的步骤一样,先建工程,只有最后一步稍有不同

然后,新建Dll.cpp文件(这里我们就不做.h文件了),敲入一下内容:

#define  DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;

DLL_API int add(int a,int b)   //实现两个整数相加

{

return a+b;

}

DLL_API int subtract(int a,int b)   //实现两个整数相减

{

return a-b;

}

然后,我们编译,生成解决方案,就会在debug文件夹下生成dllCai.dll和dllCai.lib。好,至此,动态链接库就做好了,下面我们来看怎么用,新建一个win32控制台程序,新建main.cpp内容如下:

#include <iostream>

using namespace std ;

#pragma comment(lib, "DLL.lib")

extern int add(int a,int b);

extern int subtract(int a,int b);

int main()

{

cout << add(3 ,4) << endl ;

cout << subtract(5 , 3) << endl ;

return 0 ;

}

然后把dllCai.dll和dllCai.lib拷贝到与main.cpp并列的目录下。接着,编译,链接,执行,就会看到和上一次一样的结果了。然后,我们把dllCai.lib给删了,程序照样执行,但是不能再链接了,接着,我们把dllCai.dll给删了,程序可以再编译,链接,但是执行的时候就黄了

所以,我们说:对于动态链接库,链接的时候需要.lib文件,运行的时候需要.dll文件。

至此,静态链接库和动态链接库我们就说完了,我们做一下对比和补充:

1 、 两个lib文件

我们发现,无论是静态链接库还是动态链接库,最后都有lib文件,那么两者区别是什么呢?其实,两个是完全不一样的东西。staticCai.lib的大小为4KB,dllCai.lib的大小为2KB,静态库对应的lib文件叫静态库,动态库对应的lib文件叫导入库。实际上静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

2 、 对于静态链接库,我们在编译和链接的时候已经将所有的代码都导入进来,因此,当生成可执行文件以后,可执行文件包含所有的代码。因此,在可执行文件运行时就不再需要静态库了,这也是为什么我们删掉staticCai.lib程序照样执行;而对于动态链接库,实际上,可执行文件不包含DLL中的内容,只是通过导入库(.lib)知道了相应的地址信息,因此,可执行文件在运行时动态得去加载DLL,这也是为什么我们删掉dllCai.dll后程序就不能执行了。

3 、 对于DLL,我们是可以不要lib文件的。

如果不要lib文件,我们可以通过函数指针的使用达到我们的目的:

#define  DLL_API _declspec(dllexport)

#include <iostream>

using namespace std;   //注意这里的extern "C" , 这里必须加

extern "C" DLL_API int add(int a,int b)   //实现两个整数相加

{

return a+b;

}

extern "C" DLL_API int subtract(int a,int b)   //实现两个整数相减

{

return a-b;

}

#include <iostream>

#include <Windows.h>

using namespace std ;

typedef int (*func)(int x , int y);  //函数指针

int main()

{

HINSTANCE hInstance = LoadLibrary("DLL.dll");

if(hInstance == NULL)

{

cout << "SB" << endl ;

return 0;

}

func add = (func)GetProcAddress(hInstance, "add");

func sub = (func)GetProcAddress(hInstance, "subtract");

cout << (*add)(3,4) << endl ;

cout << (*sub)(5,3) << endl ;

}

显然,这种方法没有用lib文件方便,如果为了每次调用一个函数还要自己再弄一个函数指针,多麻烦啊,所以,我们在实际开发中,用的众多的第三方扩展库,别人都是提供的:

.h  文件(类,函数的声明)

.dll 文件(类或函数的实现)

.lib 文件(导入库)

 

小结:

一、静态库

* 静态库是把程序运行时需要使用的函数编译在一个二进制文件中,扩展名为.lib。当程序link时把静态库中的二进制数据和程序其它数据放到一起。程序运行时不在需要lib和dll文件的支持。这样做的坏处是开发出来的程序占用磁盘空间较大。特别是windows系统中本来就有或很多程序运行都需要的函数完全没有必要每次开发程序时都要使用各自的静态库。

* 静态库为.lib文件形式存在

* 链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大

* 如果有多个(调用相同库函数的)进程在内存中间时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。

二、动态库

* 动态库在开发时仅是把dll中的函数名和参数放到应用程序中,应用程序运行时根据函数名和参数调用dll中的函数来运行,这样操作系统中的应用程序可以同时使用同一个dll。可以有效地节省硬盘空间,当然这样做使得程序设计更有层次。也有利于软件工程师的分工和信息安全

* 动态库以.dl文件形式存在,且一般都有一个对应的引入库以.lib文件形式存在。纯资源dll不生成.lib引入库。

>引入库和静态库的扩展名均为*.lib,但是引入库仅包含一些函数名和参数信息,没有函数体,是为调用动态库服务的,它和动态库的关系相当于.h文件和.cpp文件之间的关系;

* 动态库两种绑定方式

>静态绑定(static blnding) 使用静态绑定的程序在一开始载入内存的时候,载入程序就会把程序所有调用到的动态代码的地址算出、确定下来。这种方式使程序刚运行时的初始化时间较长,不过一但完成动态装载,程序的运行速度就很快。

2动态绑定(dynamic binding)   使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序才又去计算这部分代码的逻辑地址。所以,这种方式侄程序初始化时间较短,但运行期间的性能比不上静态绑定的程序。

* 使用动态库的两种方法(windows)

>方法一: load-time dynamic linking 
在要调用dll的应用程序链接时,将dll的输入库文件(import library,.lib文件)包含进去。具体的做 法是在源文件开头加一句#include ,然后就可以在源文件中调用dlldemo.dll中的输出文件了。

>方法二: run-time dynamic linking 
不必在链接时包含输入库文件,而是在源程序中使用LoadLibrary或LoadLibraryEx动态的载入dll。

Windows静态库和动态库的创建和使用的更多相关文章

  1. Windows下静态库与动态库的创建与使用

    Windows下静态库与动态库的创建与使用 学习内容:本博客介绍了Windows下使用Visual C++ 6.0制作与使用静态库与动态库的方法. --------CONTENTS-------- 一 ...

  2. Windows下静态库、动态库的创建和调用过程

    静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...

  3. C++ 静态库与动态库以及在 Windows上 的创建、使用

    一.什么是库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可以 ...

  4. 【C/C++开发】C++静态库与动态库以及在Linux和Windows上的创建使用

    原文出处: 吴秦的博客    这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学 ...

  5. Windows静态库和动态库的创建和使用(VS2005)

    偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...

  6. VisualGDB系列7:使用VS创建Linux静态库和动态库

    根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何在VS中创建静态库和动态库, ...

  7. C语言静态库与动态库(Windows下测试)

    转载于:https://zhidao.baidu.com/question/1946953913764139388.html,原文为Linux上测试,本文为在Windows上编译测试 我们通常把一些公 ...

  8. Windows的静态库与动态库

    Windows的静态库与动态库 1.静态库 1.1 静态库特点 运行不存在 静态库源码被链接到调用程序中 目标程序的归档 1.2 C语言静态库 C静态库的创建 创建一个静态库项目. 添加库程序,源文件 ...

  9. Makefile中静态库,动态库的创建和使用以及解压缩命令

    应用层通过操作文件操控硬件 使用制作好的工具链: 刚开始学习时,用一些已经制作好的工具链,使用以下命令解压到gcc-3.4.5-glibc-2.3.6目录 cd /work/tools tar xjf ...

随机推荐

  1. redis的主从同步

    一.redis的主从操作流程 1. 准备三个redis配置文件 #进入redis的配置文件夹,准备好这几个文件,6379不用管,默认的,和这次操作无关 [root@qishi ~]# cd /etc/ ...

  2. 3.nginx日志

    1. 自定义日志格式为json log_format json '{"@timestamp":"$time_iso8601",' '"@version ...

  3. WinForm GDI编程:Graphics画布类

    命名空间: using System.Drawing;//提供对GDI+基本图形功能的访问 using System.Drawing.Drawing2D;//提供高级的二维和矢量图像功能 using ...

  4. .Net C# 泛型序列化和反序列化JavaScriptSerializer

    项目添加引用System.Web.Extensions /// <summary> /// 泛型序列化 /// </summary> public class JsonHelp ...

  5. 数据备份及恢复(mongodump/mongorestore)

    说明 1.mongodump创建高保真的BSON文件,mongorestore可以用其恢复数据库.对于小型数据库的备份和恢复,这两个工具非常简单和高效,但对于大型数据库的备份并不理想.2.mongod ...

  6. 源码安装caffe2时遇到的问题解决办法

    https://github.com/facebookresearch/DensePose/issues/119

  7. (转)MySQL5.6主从复制技术

    原文:http://www.cnblogs.com/ilifeilong/category/1014799.html MySQL5.6复制技术(4)-MySQL主从复制过滤参数 摘要: 复制的过滤主要 ...

  8. Delphi导出word

    //导出Wordprocedure TFrm_Computing.ExportWord;varwordApp, WordDoc, WrdSelection, wrdtable, wrdtable1, ...

  9. 我的Python升级打怪之路【六】:面向对象(二)

    面向对象的一些相关知识点 一.isinstance(obj,cls) 检查实例obj是否是类cls的对象 class Foo(object): pass obj = Foo() isinstance( ...

  10. gemspec和Gemfile的不同角色作用

    [原文] http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/   我的翻译   http ...