一、静态库与动态库的区别

  目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。

  静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。

  动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。

  导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

  动态链接库 (DLL) 是作为共享函数库的可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。

  动态链接与静态链接的不同之处在于它允许可执行模块(.dll 文件或 .exe 文件)仅包含在运行时定位 DLL 函数的可执行代码所需的信息。在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。 使用动态链接代替静态链接有若干优点。DLL 节省内存,减少交换操作,节省磁盘空间,更易于升级,提供售后支持,提供扩展 MFC 库类的机制,支持多语言程序,并使国际版本的创建轻松完成。

  很多开源代码发布的惯用方式:

  1. 预编译的开发包:包含一些.dll文件和一些.lib文件。其中这里的.lib就是导入库,而不要错以为是静态库。但是引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。而.dll则最好放到最后产生的应用程序exe执行文件相同的目录。这样运行时,就会自动调入动态链接库。

  2. 用户自己编译: 下载的是源代码,按照readme自己编译。生成很可能也是.dll + .lib(导入库)的库文件

  3. 如果你只有dll,并且你知道dll中函数的函数原型,那么你可以直接在自己程序中使用LoadLibary调入DLL文件,GetProcAddress

二、静态链接库

  静态链接库的创建和使用都比较的简单,我们直接看个理解就可以了。

  在vs2010中新建一个Win32控制台的静态链接库工程static_lib,在工程中创建文件lib.h和lib.cpp这两个文件,lib.h和lib.cpp的源代码如下:

//lib.h文件

#ifndef LIB_H
#define LIB_H extern "C" int add(int a, int b); //声明为C调用方式的外部调用函数 #endif //lib.cpp文件 #include "lib.h" int add(int a, int b)
{
return a + b;
}

  直接编译这个工程,在debug目标中就会自动生成static_lib.lib。在static_lib工程的工作区中新建libcall工程,它只有一个文件test.cpp,代码如下:

#include "../static_lib/lib.h"
#include <stdio.h>
#pragma comment(lib, "..\\debug\\static_lib.lib") int main(int argc, char *argv[])
{
printf("4 + 5 = %d\n", add(, ));
}

  静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明白这个概念。代码中#pragma comment(lib, "..\\debug\\static_lib.lib")的意思是指本文件生成的.obj文件应与tatic_lib.lib一起链接。如果不用#pragma comment指定,则可以直接在vs中设置,如图1,在libcall工程的属性页面,通过链接器->常规->附加库目录添加tatic_lib.lib所在的目录,通过链接器->输入->附加依赖项添加static_lib.lib到项目中。

图1

  直接运行就可以看到屏幕上输出结果。

  现在我们来看看static_lib.lib的反汇编结果:

Microsoft (R) COFF/PE Dumper Version ...
Copyright (C) Microsoft Corporation. All rights reserved. Dump of file D:\My Documents\Visual Studio \Projects\static_lib\Debug\static_lib.lib File Type: LIBRARY _add:
: push ebp
: 8B EC mov ebp,esp
: EC C0 sub esp,0C0h
: push ebx
0000000A: push esi
0000000B: push edi
0000000C: 8D BD FF FF FF lea edi,[ebp+FFFFFF40h]
: B9 mov ecx,30h
: B8 CC CC CC CC mov eax,0CCCCCCCCh
0000001C: F3 AB rep stos dword ptr es:[edi]
0000001E: 8B mov eax,dword ptr [ebp+]
: 0C add eax,dword ptr [ebp+0Ch]
: 5F pop edi
: 5E pop esi
: 5B pop ebx
: 8B E5 mov esp,ebp
: 5D pop ebp
0000002A: C3 ret Summary 5FC .debug$S
.debug$T
.drectve
.rtc$IMZ
.rtc$TMZ
2B .text

  从上面的汇编代码可以看到static_lib.lib直接包含了add的函数代码,这也应证了前面说的代码直接放在静态库的lib文件中。

参考:http://dev.yesky.com/228/2141728.shtml

http://www.cnblogs.com/chio/archive/2008/08/05/1261296.html

vc下的静态链接库与动态链接库(一)的更多相关文章

  1. linux下静态链接库和动态链接库

    关于链接库的知识,网上太多资料了,但是并不代表我很熟悉.今天遇到了 一个问题,就是由于静态链接库和ubuntu系统不兼容导致的,虽然花了点时间才搞定 但是,其中暴露的问题也不少. 没有区分好静态链接库 ...

  2. Linux环境下c语言静态链接库和动态链接库创建和使用

    库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 面对比一下两者: 静态链接库:当要使用时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功, ...

  3. 介绍静态链接库和动态链接库的差别,及在VC++6.0中的建立和使用

    首先介绍一下链接库:链接库分为动态链接库和静态链接库两种 LIB是静态链接库,在程序编译连接的时候是静态链接,其相应的文件格式是.lib. 即当程序採用静态链接库的时候..lib文件里的函数被链接到终 ...

  4. linux c静态链接库与动态链接库

    库函数是我们编程的时候经常用到的,我们协作编程的时候可以将常用的函数封装成库供大家使用,这样能够提高大家的工作效率.对于库函数,它分为动态链接库和静态链接库.对于静态链接库我们必须是连接到可执行文件中 ...

  5. Makefile常用万能模板(包括静态链接库、动态链接库、可执行文件)

    本文把makefile 分成了三份:生成可执行文件的makefile,生成静态链接库的makefile,生成动态链接库的makefile. 这些makefile都很简单,一般都是一看就会用,用法也很容 ...

  6. linux静态链接库与动态链接库详解

    一顺便说说了哦  通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(e ...

  7. [拾零]C/C++_代码复用的实现_静态链接库_动态链接库_使用.def导出

    1 静态链接库 1.1 创建静态链接库: 1.在VC6中创建项目:Win32 Static Library 2.在项目中创建两个文件:xxx.h 和 xxx.cpp 3.编译 1.2 使用静态链接库 ...

  8. VC++ DLL 2 静态链接库

    这一篇以VS2013为例子介绍怎样编写一个静态链接库和调用. 1.打开VS2013,新建Visual C++ 的win32项目: 新建后工程分支如下: 添加头文件和源文件: 编写头文件和源文件内容: ...

  9. Linux下 静态链接库 和 动态链接库

    先来说说C/C++编译过程 编译: 检查语句符号定义,将C/C++代码翻译生成中间语言. 链接: 将中间代码整合,生成可执行的二进制代码. 简单的说,库文件都是一种特殊的中间语言文件,静态库还是一种特 ...

随机推荐

  1. 速度极快的导出excel

    public class Export2Excel { #region [导出文件,使用文件流] /// <summary> /// 导出文件,使用文件流.该方法使用的数据源为DataTa ...

  2. python,django安装

    环境:win7 64位 软件:python3.4.3,jdango1.8,PyDev,pymysql0.7 一:安装python 1.安装好python好后,配置环境变量,可以参考其它的博客,本博客只 ...

  3. MySQL表名和数据库关键字相同解决办法

    今天改他们的代码的时候,遇到了MySQL表名和数据库关键字的问题. 由于表名是关键字,导致增删改查都报错. Hibernate: select leave0_.id as id22_, leave0_ ...

  4. int.Parse()之异常

    首先对不起各位读者,我必须发泄一下,为了清明节能顺利的去洛阳玩,我周四赶出了一篇博客,就在快写完提交的时刻,11:30分断网了!!断网了!!断!!网!!了!!是的,你没有听错,他就这样毫无征兆的断网了 ...

  5. 关于call和apply函数的区别及用法

    call和apply函数是function函数的基本属性,都可以用于更改函数对象和传递参数,是前端工程师常用的函数.具体使用方法请参考以下案列: 例如: 申明函数: var fn = function ...

  6. K线图学习

    本博文(适合入门的股民朋友)内容来自网络,股市有风险,入市需谨慎 一.起源 K线图(Candlestick Charts)又称蜡烛图.日本线.阴阳线.棒线等,常用说法是“K线”,起源于日本十八世纪德川 ...

  7. 初学者-PHP笔记

    PHP介绍 PHP 是 "PHP Hypertext Preprocessor" 的首字母缩略词 PHP 是一种被广泛使用的开源脚本语言 PHP 脚本在服务器上执行 PHP 没有成 ...

  8. 深入浅出 妙用Javascript中apply、call、bind

    apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...

  9. 【五】将博客从jekyll迁移到了hexo

    本系列有五篇:分别是  [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面  [二]jekyll 的使用 :主要是jekyll的配置  [三]Markdo ...

  10. Microsoft Avro介绍

    Microsoft发布了他们自己对Apache Avro通信协议的实现.Avro被描述为"紧凑的二进制数据序列化格式,类似于Thrift或者Protocol Buffers",同时 ...