我们可以创建一种文件里面包含了很多函数和变量的目标代码,链接的时候只要把这个文件指示给链接程序就自动地从文件中查找符合要求的函数和变量进行链接,整个查找过程根本不需要我们操心。
这个文件叫做 “库(Libary)”,平时我们把编译好的目标代码存储到“库”里面,要用的时候链接程序帮我们从库里面找出来。
静态链接库:
在早期库的组织形式相对简单,里面的目标代码只能够进行静态链接,所以我们称为“静态库”,静态库的结构比较简单,其实就是把原来的目标代码放在一起,链接程序根据每一份目标代码的符号表查找相应的符号(函数和变量的名字),找到的话就把该函数里面需要定位的进行定位,然后将整块函数代码放进可执行文件里,若是找不到需要的函数就报错退出。
静态库的两个特点:
#1链接后产生的可执行文件包含了所有需要调用的函数的代码,因此占用磁盘空间较大。
#2如果有多个(调用相同库函数的)进程在内存中同时运行,内存中就存有多份相同的库函数代码,因此占用内存空间较多。
动态链接库:
动态链接库就是为了解决这些问题而诞生的技术,顾名思义,动态链接的意思就是在程序装载内存的时候才真正的把库函数代码链接进行确定它们的地址,并且就算有几个程序同时运行,内存也只存在一份函数代码。
动态库的代码必须满足这样一种条件:能够被加载到不同进程的不同地址,所以代码要经过特别的编译处理,我们把这种经过特别处理的代码叫做“位置无关代码(Position independed Code .PIC)”.
根据载入程序何时确定动态代码的逻辑地址,可以把动态装载分为两类。
#1 静态绑定(static binding)
使用静态绑定的程序一开始载入内存的时候,载入程序就会把程序所有调用到的动态代码的地址算出确定下来,这种方式使程序刚运行的初始化时间较长,不过旦完成动态装载,程序的运行速度就很快。
#2动态绑定(dynamic binding)
使用这种方式的程序并不在一开始就完成动态链接,而是直到真正调用动态库代码时,载入程序才计算(被调用的那部分)动态代码的逻辑地址,然后等到某个时候,程序又需要调用另外某块动态代码时,载入程序又去计算这部分代码的逻辑地址,所以,这种方式使程序初始化时间较短,但运行期间的性能比不上静态绑定的程序。
平时默认进行链接的标准 C/C++ 函数就是动态库。
Note:
内存中的动态代码只有一份副本,但动态库的数据仍然可能有多份副本,因为每一个链接到动态的进程都可能会修改库的数据,每当出现这种情况的时候,操作系统就复制出一份数据副本,然后修改进程的地址空间映射,使它指向新的数据副本,于是进程最后修改的只是属于自己的那份数据。
一、如何使用静态链接库?
1. .h和.lib放到你工程目录下面
2.在stdafx.h里面,加入
#include "xxx.h"
#pragma comment(lib,"xxx.lib")
二、动态链接库转换为静态链接库?
> cd /c/usr/src/lib
> pexports.exe ../bin/iconv.dll > iconv.def
> dlltool.exe -e libiconv.exp -l libiconv.a -D iconv.dll -d iconv.def -z libiconv.def -k -v
> ranlib libiconv.a
动态.dll -> 静态.lib:
使用DLL to Lib工具转换,此工具收费。
动态.dll _> 动态.lib:
使用VC的lib.exe工具,可以由.DLL生成.Lib
三、C 静态链接库LIB的制作?
要创建静态库,选择File->New菜单,弹出New对话框。选择Projects标签,在项目类型列表框中选择Win32 Static Library,在Name中输入mymath,表明要创建一个mymath.lib的静态库文件。
然后用Project->Add to Project->Files菜单往mymath工程中加入以下两个文件:
//MyLib.h
#ifndef _MYMATH_H
#define _MYMATH_H
extern "C"
{
int Summary(int n);
}
#endif
//MyLib.c
extern "C" int Summary(int n)
{
return n+2;
}
//编译程序
//使用
#i nclude "MyLib.h"
LIB MyLib.lib
就可以使用导出的函数
四、如何在VC.NET中制作并使用动态链接库DLL?
1、将C++类做成DLL
建立一个MFC DLL工程,PacketTransfer;将类的头文件搞到PacketTransfer.h中,并在要在外部调用的类声明前加_declspec(dllexport),如:要在外内调用CPacketTransfer类,可对该类做声明:
class _declspec(dllexport) CPacketTransfer
{
……
};
将类的定义文件内容拷到Sample.cpp中,然后生成该工程,生成的文件有:PacketTransfer.dll和PacketTransfer.lib
2、调用DLL中的C++类
将PacketTransfet.h,PacketTransfer.dll和PacketTransfer.lib拷贝到要调用的工程目录下,在工程属性中加入输入:PacketTransfer.lib,并包含头文件PacketTransfer.h,就可以使用类CPacketTransfer了:
CPacketTransfer temp,*pTest;……
3、将C或C++函数接口做成DLL
建立一个MFC DLL工程,api;将用到的头文件声明拷贝加到api.h中,将其它代码拷到api.cpp中,并在所有要调用的接口函数声明前加入导出声明,如:
extern "C" _declspec(dllexport) bool MakeMD5File(char *file,char *key);
然后生成该工程,得到文件api.dll和api.lib
4、使用DLL中的接口
将api.dll和api.lib拷到工程目录下,在工程属性中加入输入:api.lib,然后在使用接口函数前用extern "C" _declspec(dllimport)声明该接口即可:
extern "C" _declspec(dllimport) bool MakeMD5File(char *file,char *key);
然后可以使用该函数的,也可以用LoadLibrary()等系统API直接调用DLL中的接口.
五、使用动态链接库DLL的方法?
我们可以把 .dll 文件想象成 .c 或 .cpp 文件,
函数的主体在这个文件中,而函数的定义在 .h 文件中,
我们把 .lib 文件想象成 .dll 中函数的声明,
因此,只要把 .h, .lib, .dll 三个文件安排好,
让你的程序能找到它们就可以像使用自己写的函数一样适用 .dll 中的函数了。
具体方法如下:
1、建立一个简单的C程序
2、添加想要使用的 .dll 中的函数(这是opencv库中的功能)
此时会提示有错误,没有任何代码,就是用函数和结构体,当然会告诉你没定义了;-)
3、将 .h 文件拷贝过来
至于你应该拷贝哪个 .h 文件,你自己必须知道,就是那个 .dll 文件对应的 .h 文件
现在编译后错误少了两个,确切的说应该是错误都去掉了,多了一个新错误,说没有cxcore.h文件
这是拷贝过来的highgui.h文件需要的,我们来看看,
看到了吧,就是说这个文件必须引用另一个文件。
真实情况是这样的:这个 .dll 文件需要另一个 .dll 文件的支持,我们如发泡制,也把头文件拷贝过来
又出现一个新的错误,缺少cxtypes.h文件,这是刚拷贝来的cxcore.h文件需要的,我们继续拷贝
4、 注意啦!要看看错误的类型,已经不是编译错误啦,而是连接错误,说明语法已经没有错误,是缺少函数的实体了。
现在的情况就相当于我们已经在 .h 文件中定义了调用的函数,但是没有给出函数实体。我们把函数实体 .dll 文件
拷贝过来。应该拷贝的 .dll 文件,你自己应该知道,如果不知道,sorry,错啦
刚才的错误是连接错误,这个时候它找的是函数的声明,因为 .dll 文件只有在运行时才会涉及到。为了证明这一点,
我们把刚拷贝来的 .dll 文件都删除。然后把 .lib 文件拷贝来
为什么还有错误? 因为你并没有告诉程序应该连接它,怎么样,没有任何错误了吧。我们运行看看
这就是运行时错误了,因为没有可用的 .dll 文件,因此提示错误,按照它提示的 .dll 文件,我们把它拷贝过来。
又提示了一个新的错误,缺少另一个 .dll文件,我说过了,前面的那个 .dll文件需要后面的这个支持.
这回运行出来了.
六、VC++中使用静态链接库和动态链接库小结?
最近在VC++使用GSL(GNU科学计算库)静态库和动态库时遇到了一些问题,做个小结,以备参考。
静态库包括.lib和.h文件,在工程中使用静态库分为3步:
1在工程中加入静态库,有两种方法:
方法一:项目设置中引用.lib,project-setting-link-object/library modules中添加.lib;(需要在tools/options设置正确的引用路径)
方法二:在项目中直接加入lib,project-add to project-files,选择正确的.lib。
2在工程中包括.h文件;(可能 需要在tools/options设置正确的引用路径)
3在工程中使用静态库中的函数;--大功告成!
动态链接库一般包括.lib(导出函数),.h,.dll,使用动态库有两种情况:
1隐式链接,同使用静态库相似,分为三步:引用.lib,包含头文件,使用导出函数;
2动态加载,直接使用LoadLibrary 加载所需的动态库,然后指定所需的导出函数,效率最高!
七、为什么要使用动态链接库(DLL)?
提起DLL您一定不会陌生,在Windows中有着大量的以DLL为后缀的文件,它们是保证Windows正常运行和维护升级的重要保证。(举个例子,笔者的Win95 System目录下尽有500多个DLL文件。)其实,DLL是一种特殊的可执行文件。说它特殊主要是因为一般它都不能直接运行,需要宿主程序比如*.EXE程序或其他DLL的动态调用才能够使用。简单的说,在通常情况下DLL是经过编译的函数和过程的集合。
使用DLL技术主要有以下几个原因:
1、减小可执行文件大小。
DLL技术的产生有很大一部分原因是为了减小可执行文件的大小。当操作系统进入Windows时代后,其大小已经达到几十兆乃至几百兆。试想如果还是使用DOS时代的单执行文件体系的话一个可执行文件的大小可能将达到数十兆,这是大家都不能接受的。解决的方法就是采用动态链接技术将一个大的可执行文件分割成许多小的可执行程序。
2、实现资源共享。
这里指的资源共享包括很多方面,最多的是内存共享、代码共享等等。早期的程序员经常碰到这样的事情,在不同的编程任务中编写同样的代码。这种方法显然浪费了很多时间,为了解决这个问题人们编写了各种各样的库。但由于编程语言和环境的不同这些库一般都不能通用,而且用户在运行程序时还需要这些库才行,极不方便。DLL的出现就像制定了一个标准一样,使这些库有了统一的规范。这样一来,用不同编程语言的程序员可以方便的使用用别的编程语言编写的DLL。另外,DLL还有一个突出的特点就是在内存中只装载一次,这一点可以节省有限的内存,而且可以同时为多个进程服务。
3、便于维护和升级。
细心的朋友可能发现有一些DLL文件是有版本说明的。(查看DLL文件的属性可以看到,但不是每一个DLL文件都有)这是为了便于维护和升级。举个例子吧,早期的Win95中有一个BUG那就是在闰年不能正确显示2月29日这一天。后来,Microsoft发布了一个补丁程序纠正了这个BUG。值得一提的是,我们并没有重装Win95,而是用新版本的DLL代替了旧版本的DLL。(具体是哪一个DLL文件笔者一时想不起来了。)另一个常见的例子是驱动程序的升级。例如,著名的DirectX就多次升级,现在已经发展到了6.0版了。更妙的是,当我们试图安装较低版本的DLL时,系统会给我们提示,避免人为的操作错误。例如我们升级某硬件的驱动程序时,经常碰到Windows提示我们当前安装的驱动程序比原来的驱动程序旧。
4、比较安全。
这里说的安全也包括很多方面。比如,DLL文件遭受病毒的侵害机率要比普通的EXE文件低很多。另外,由于是动态链接的,这给一些从事破坏工作的“高手”们多少带来了一些反汇编的困难。
相关推荐
总结,C++的静态链接库和动态链接库都是代码重用的有效手段,它们在项目开发中扮演着重要的角色。理解它们的工作原理和选择合适的链接库类型,有助于优化程序性能、简化部署流程以及提高软件的可维护性。在实践中,...
### 静态链接库与动态链接库...静态链接库和动态链接库各有优缺点。静态库适合于那些不需要频繁更新的场景,而动态库则更适合于需要动态加载、易于更新和共享资源的情况。开发者应根据项目的具体需求选择合适的库类型。
在现代软件开发中,为了代码复用和模块化设计,经常会用到静态链接库和动态链接库这两种形式的库。静态链接库在编译时期与应用程序链接,而动态链接库则在运行时期加载。 首先,我们来谈谈静态链接库。创建静态库的...
##### 4.1 动态链接库转静态链接库 可以使用一些工具将动态链接库转换成静态链接库。例如,通过命令行工具`dlltool`和`ranlib`组合使用可以实现这一转换: ```bash cd /c/usr/src/lib pexports.exe ../bin/iconv....
在Linux系统中,C语言的库分为静态链接库和动态链接库两种类型,它们都是为了实现代码重用和模块化设计的重要工具。本篇文章将深入浅出地介绍这两种链接库的原理、创建方法以及如何在程序中使用。 一、静态链接库 ...
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。 在静态链接库中,所有的指令都包含在最终生成的EXE文件中,...
静态链接库和动态链接库是两种主要的链接库类型,它们各有优缺点,适用于不同的开发场景。本篇文章将详细探讨这两种链接库的概念、创建过程以及如何在C++项目中使用它们。 **静态链接库(Static Linking Library)*...
动态链接库(Dynamic Link Library, DLL)和静态链接库(Static Link Library, SLB)是Windows操作系统中两种常见的库文件类型,它们在程序编译和运行时起着至关重要的作用。理解二者的区别有助于我们更好地进行软件...
本文将详细介绍静态链接库和动态链接库的制作和使用,包括函数库的概念、静态链接库和动态链接库的定义、制作和使用方法,以及在实际开发中如何正确地使用静态链接库和动态链接库。 一、函数库的概念 函数库是一些...
### Linux下使用动态链接库和静态链接库的项目建立及单步调试 #### 一、动态链接库的建立和单步调试 ##### 1.1 编写用户接口文件 `datetime.h` 首先,创建了一个头文件`datetime.h`,该文件定义了两个结构体:`...
在Linux系统中,链接库是实现程序功能复用的关键组件,分为静态链接库和动态链接库两种类型。本文主要探讨这两种库的创建、使用及其特点。 1. 静态函数库 静态库通常以`.a`为后缀,如`libxxx.a`。在编译过程中,...
链接库大致可以分为两大类:静态链接库(Static Library)和动态链接库(Dynamic Link Library,简称DLL)。本文将深入探讨这两类链接库之间的差异及其应用场景。 #### 静态链接库(Static Library) 静态链接库是...
动态链接库(DLL)和静态链接库(LIB)是Windows操作系统中两种常见的库文件类型,它们在软件开发中起着至关重要的作用。本篇文章将深入探讨这两种库的区别、生成过程以及如何在实际项目中使用。 首先,我们来看...
在Linux系统中,静态链接库和动态链接库是两种主要的库类型,它们在软件开发中扮演着重要的角色。静态链接库(.a文件)和动态链接库(.so文件)的主要区别在于链接方式和内存占用。 静态链接库在编译时会被合并到...
在Linux系统中,开发软件时我们常常会遇到静态链接库和动态链接库的概念。这两个库在程序编译和运行过程中起着至关重要的作用。这里,我们将深入探讨它们的区别以及如何在Linux Shell环境下创建和使用它们。 1. **...
静态链接库和动态链接库是两种主要的链接库类型,它们在程序编译和运行时有不同的工作方式。本篇文章将深入探讨这两种链接库在MFC(Microsoft Foundation Classes)环境下的使用,并通过提供的代码实例来帮助理解。 ...
动态链接库和静态链接库是两种不同的库文件类型,它们在编译和链接过程中扮演着重要的角色。下面我们将详细探讨这两种库文件的特点和使用方法。 动态链接库 动态链接库(Dynamic Link Library,DLL)是一种可以被...
综上所述,静态库和动态库各有千秋,在实际开发中应根据具体需求选择合适的类型。了解两者的区别以及它们的工作原理对于优化应用程序性能和简化软件维护至关重要。通过合理利用这两种库类型,开发者可以创建出更加...
在 Linux 系统中,函数库的链接可以分为静态链接库和动态链接库两种。静态链接库是在编译时期完成的,所有相关的对象文件和函数库被链接合成一个可执行文件。程序在运行时,不再需要函数库的参与,因为所有需要的...