
一、动态链接库的概念\x0d\ 动态链接库(Dynamic Link Library,缩写为DLL)是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。动态链接库文件的扩展名一般是dll,也有可能是drv、sys和fon,它和可执行文件(exe)非常类似,区别在于DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。\x0d\ 动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。\x0d\ 一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射文件实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间,如果一个DLL被多个进程调用,每个进程都会收到该DLL的一份映像。
两者区别:a,静态库的使用需要:1包含一个对应的头文件告知编译器lib文件里面的具体内容2设置lib文件允许编译器去查找已经编译好的二进制代码b,动态库的使用:程序运行时需要加载动态库,对动态库有依赖性,需要手动加入动态库c,依赖性:静态链接表示静态性,在编译链接之后,lib库中需要的资源已经在可执行程序中了,也就是静态存在,没有依赖性了动态,就是实时性,在运行的时候载入需要的资源,那么必须在运行的时候提供需要的动态库,有依赖性,运行时候没有找到库就不能运行了d,区别:简单讲,静态库就是直接将需要的代码连接进可执行程序;动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行。做成静态库可执行文件本身比较大,但不必附带动态库做成动态库可执行文件本身比较小,但需要附带动态库链接静态库,编译的可执行文件比较大,当然可以用strip命令精简一下(如:striplibtesta),但还是要比链接动态库的可执行文件大。程序运行时间速度稍微快一点。静态库是程序运行的时候已经调入内存,不管有没有调用,都会在内存里头。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。其在编译程序时若链接,程序运行时会在系统指定的路径下搜索,然后导入内存,程序一般执行时间稍微长一点,但编译的可执行文件比较小;动态库是程序运行的时候需要调用的时候才装入内存,不需要的时候是不会装入内存的。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。动态链接库的特点与优势首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:1可以实现进程之间的资源共享。什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候, *** 作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。2将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows就是一个很好的例子。3甚至可以真正坐到链接载入完全由程序员在程序代码中控制。程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的 *** 作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写 *** 作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。静态库:在编译的时候加载生成目标文件,在运行时不用加载库,在运行时对库没有依赖性。动态库:在目标文件运行时加载,手动加载,且对库有依赖性。具体在开发中用到哪种库,我觉得还是根据实际的内存大小,ROM大小,运行的速度等综合考虑。
动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的EXE文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。静态链接的执行程序能够在其它同类 *** 作系统的机器上直接运行,比如一个EXE文件是在WIN2000系统上静态链接的,那么将该文件直接拷贝到另一台WIN2000的机器上,是可以运行的。而动态链接的执行程序则不可以,除非把该EXE文件所需的DLL文件都一并拷贝过去,或者对方机器上也有所需的相同版本的DLL文件,否则是不能保证正常运行的。不过静态链接得到的文件比较大,而动态链接得到的文件比较小。
大家都知道静态链接对SEO(搜索引擎优化 Search Engine Optimization)有很大益处,而且静态链接对服务器的负载很小,但静态链接的缺点是不能随时更新。对于伪静态的优点,这个并不好讲,伪相比动态链接而言,并没有提到速度的提升,相比较而言,因为是假静态链接,其实还是一个动态链接,也是同样需要翻译为静态链接的。最大的好处就是让搜索引擎把自己的网页当做静态网页来处理。
pthreads-win32是windows下的pthread库,它默认采用的是动态链接库的链接方式,因此在使用该库的程序都需要带上一个动态库pthreadVC2dll,感觉挺不方便的,下面介绍如何静态链接pthreads-win32:
首先要编译静态库: 从ftp //sources redhat com/pub/pthreads-win32/下载最新的库安装包,笔者下载的是pthreads-w32-2-8-0-releaseexe,自解压到一个目录,用vc7打开pthreads2目录下的pthreaddsw,会提示工程版本转换,选择全是,然后打开该工程的属性页,在“常规”选项页的配置类型选择“静态库(lib)”,在“c/c++”选项页的预处理器定义删除_USRDLL和PTW32_BUILD,添加PTW32_STATIC_LIB,确定保存即可。当然,你需要根据你的需要选择运行时库的类型。最后重新生成pthread便可生成我们需要的pthreadlib。
下面讲述如何使用前面生成的静态库:新建一个控制台工程,将pthreadlib拷贝到工程目录,在预处理器定义中添加PTW32_STATIC_LIB,附加包含目录添加pthreads-win32代码所在目录,笔者是E:/pthreads/pthreads2,附加依赖项添加Ws2_32lib和pthreadlib即可,简单使用代码如下:
#include <iostream>
#include "pthreadh"
void Function_t(void Param)
{
std::cout << "我是线程!" << std::endl;
pthread_t myid = pthread_self();
printf( "线程ID = %d", myid );
return NULL;
}
int main()
{
#ifdef PTW32_STATIC_LIB
pthread_win32_process_attach_np();
#endif
pthread_t pid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&pid, &attr, Function_t, NULL);
std::cout << "========================================" << std::endl;
getchar();
pthread_attr_destroy(&attr);
#ifdef PTW32_STATIC_LIB
pthread_win32_process_detach_np();
#endif
return 1;
}
其中
#ifdef PTW32_STATIC_LIB
pthread_win32_process_attach_np();
#endif
#ifdef PTW32_STATIC_LIB
pthread_win32_process_detach_np();
#endif
对于静态链接方式非常重要,如果没有这段代码,线程将创建失败。
首先我先简单介绍一下静态链接库的作用。我们知道,C/C++程序生成目标代码的过程有,编写代码,编译代码,连接代码,生成目标代码。在连接代码的时候,会将编译后的二进制代码连接成目标代码。但是,有些时候。我们想让程序导入必要的代码,而不想导入无用的代码到我们的程序中。我们该如何呢?很简单,使用静态连接库。使用它我们就可以实现将在程序中使用的函数导入的目的。
下面我们来一步步的学做静态链接库并且学会如何使用。
我们现在先写一段代码,你可以用Dev也可以用记事本也可以用任何你喜欢的文本编辑器。像我就比较喜欢vi或者emacs作为平时的文本编辑器。话说远了,现在言规正传。我们写下下面的代码。
//HelloWorldc
#include <stdioh>
void HelloWorld(void)
{
printf("Hello World");
}
上面那段C代码各位应该很熟悉的吧,那么经典的Hello World好让我怀念啊。保存为HelloWorldc以后我们就开始生成了。
首先,我们先编译HelloWorldc
gcc -c HelloWorldc -o HelloWorldo
这样我们得到一个二进制的文件HelloWorldo
接着我们生成静态库。
ar cqs libHelloWorlda HelloWorldo
这样我们党额静态链接库就好了。如果有需要可以将其他的二进制文件名加HelloWorldo的后面将他们连接成一个静态链接库。另外,生成的静态库文件名必须为liba
好了,现在我们来使用我们的库吧。
接下来,我们为了能够使用方便,写一个如下头文件。
//HelloWorldh
void HelloWorld(void);
接着我们开始使用我们刚才生成的静态库。写一个mainc的文件。
//mainc
#include "HelloWorldh"
int main(void)
{
HelloWorld();
return(0);
}
使用gcc编译,假设我们这里所有的文件都保存在同一个目录下。
gcc -c mainc -o maino
然后我们连接程序。
gcc maino -o mainexe -L"/" -lHelloWorld
如果顺利我们会得到一个mainexe的文件。
在控制台下输入mainexe或者main就可以出现 Hello World 这组单词。
看了上面的文章是否很兴奋想要生成自己的静态链接库?其实,我个人觉得mingw32生成静态链接库要比VC生成的简单。不知道你有没有这样的感觉。
当然,如果你要在Dev下使用静态连接库,也是可以的。方法我在上一章已经说过了。只是,如果你要使用自己的库必须设置路径。
只要在连接器参数中添加 -L"你的库的所在的文件夹" 或者 将你的库保存到Dev安装目录中的lib目录中。
以上就是关于什么是静态链接库什么是动态链接库他们有什么区别全部的内容,包括:什么是静态链接库什么是动态链接库他们有什么区别、linux 动态链接和静态链接的区别、请问静态链接和动态链接之间各有什么优缺点等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)