版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Linux 关于动态链接库以及静态链接库的一些概念库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a使用库当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。现在假设有一个叫hello的程序开发包,它提供一
2、个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数/* hello.h */void sayhello();另外还有一些说明文档。这一个典型的程序开发包结构1.与动态库连接linux默认的就是与动态库连接,下面这段程序testlib.c使用hello库中的sayhello()函数/*testlib.c*/#include #include int main()sayhello();return 0;使用如下命令进行编译$gcc -c testlib.c -o testlib.o用如下命令连接:$gcc testli
3、b.o -lhello -o testlib在连接时要注意,假设libhello.o 和libhello.a都在缺省的库搜索路径下/usr/lib下,如果在其它位置要加上-L参数与与静态库连接麻烦一些,主要是参数问题。还是上面的例子:$gcc testlib.o -o testlib -WI,-Bstatic -lhello注:这个特别的"-WI,-Bstatic"参数,实际上是传给了连接器ld.指示它与静态库连接,如果系统中只有静态库当然就不需要这个参数了。如果要和多个库相连接,而每个库的连接方式不一样,比如上面的程序既要和libhello进行静态连接,又要和libbye
4、进行动态连接,其命令应为:$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye3.动态库的路径问题为了让执行程序顺利找到动态库,有三种方法:(1)把库拷贝到/usr/lib和/lib目录下。(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libhello.so在/home/ting/lib目录下,以bash为例,使用命令:$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib4.查看库中的符号有时候可能需要查看一个库中到底有哪些函数,
5、nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。例如,假设开发者希望知道上央提到的hello库中是否定义了 printf():$nm libhello.so |grep printfU printfU表示符号printf被引用,但是并没有在函数内定义,由此可以推断,要正常使用hello库,必须有其它库支持,再使用ldd命令
6、查看hello依赖于哪些库:$ldd hello从上面的结果可以继续查看printf最终在哪里被定义,有兴趣可以go on生成库第一步要把源代码编绎成目标代码。以下面的代码为例,生成上面用到的hello库:/* hello.c */#include void sayhello()printf("hello,worldn");用gcc编绎该文件,在编绎时可以使用任何全法的编绎参数,例如-g加入调试代码等:gcc -c hello.c -o hello.o1.连接成静态库连接成静态库使用ar命令,其实ar是archive的意思$ar cqs libhello.a hello.o
7、2.连接成动态库生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:另外再建立两个符号连接:这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同其中,xxxx是库的名字,major是主版本号,minor 是次版本号=摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统
8、的动态库由于格式不同,在需要不同操作系统调用时需要进行动态库程序移植。本文分析和比较了两种操作系统动态库技术,并给出了将Visual C+编制的动态库移植到Linux上的方法和经验。1、引言动态库(Dynamic Link Library abbr,DLL)技术是程序设计中经常采用的技术。其目的减少程序的大小,节省空间,提高效率,具有很高的灵活性。采用动态库技术对于升级软件版本更加容易。与静态库(Static Link Library)不同,动态库里面的函数不是执行程序本身的一部分,而是根据执行需要按需载入,其执行代码可以同时在多个程序中共享。在Windows和Linux操作系统中,都可采用这
9、种方式进行软件设计,但他们的调用方式以及程序编制方式不尽相同。本文首先分析了在这两种操作系统中通常采用的动态库调用方法以及程序编制方式,然后分析比较了这两种方式的不同之处,最后根据实际移植程序经验,介绍了将VC+编制的Windows 动态库移植到Linux下的方法。2、动态库技术2.1 Windows动态库技术动态链接库是实现Windows应用程序共享资源、节省内存空间、提高使用效率的一个重要技术手段。常见的动态库包含外部函数和资源,也有一些动态库只包含资源,如Windows字体资源文件,称之为资源动态链接库。通常动态库以.dll,.drv、.fon等作为后缀。相应的windows静态库通常以
10、.lib结尾,Windows自己就将一些主要的系统功能以动态库模块的形式实现。Windows动态库在运行时被系统加载到进程的虚拟空间中,使用从调用进程的虚拟地址空间分配的内存,成为调用进程的一部分。DLL也只能被该进程的线程所访问。DLL的句柄可以被调用进程使用;调用进程的句柄可以被DLL使用。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关,可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括
11、变量)都归调用它的线程或进程所有。根据调用方式的不同,对动态库的调用可分为静态调用方式和动态调用方式。(1)静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责对DLL调用次数的计数),调用方式简单,能够满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须在源文件中声明一下。 LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名,不含有实际的代码。Lib文件包含的信息进入到生成的应用程序中,被调用的DLL文件会在应用程序加载时同时加载在到内存
12、中。(2)动态调用,即显式调用方式,是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,比较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。在Windows系统中,与动态库调用有关的函数包括:LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。在windows中创建动态库也非常方便和简单。在Visual C+中,可以创建不用MFC而直接用C语言写的DLL程序,也可以创建基于MF
13、C类库的DLL程序。每一个DLL必须有一个入口点,在VC+ 中,DllMain是一个缺省的入口函数。DllMain负责初始化(Initialization)和结束(Termination)工作。动态库输出函数也有两种约定,分别是基于调用约定和名字修饰约定。DLL程序定义的函数分为内部函数和导出函数,动态库导出的函数供其它程序模块调用。通常可以有下面几种方法导出函数:采用模块定义文件的EXPORT部分指定要输入的函数或者变量。使用MFC提供的修饰符号_declspec(dllexport)。以命令行方式,采用/EXPORT命令行输出有关函数。在windows动态库中,有时需要编写模块定义文件(.
14、DEF),它是用于描述DLL属性的模块语句组成的文本文件。2.2 Linux共享对象技术在Linux操作系统中,采用了很多共享对象技术(Shared Object),虽然它和Windows里的动态库相对应,但它并不称为动态库。相应的共享对象文件以.so作为后缀,为了方便,在本文中,对该概念不进行专门区分。Linux系统的/lib以及标准图形界面的/usr/X11R6/lib等目录里面,就有许多以so结尾的共享对象。同样,在Linux 下,也有静态函数库这种调用方式,相应的后缀以.a结束。Linux采用该共享对象技术以方便程序间共享,节省程序占有空间,增加程序的可扩展性和灵活性。Linux还可以
15、通过LD-PRELOAD变量让开发人员可以使用自己的程序库中的模块来替换系统模块。编译生成动态连接库后,进而可以在程序中进行调用。在Linux中,可以采用多种调用方式,同Windows的系统目录(.system32等) 一样,可以将动态库文件拷贝到/lib目录或者在/lib目录里面建立符号连接,以便所有用户使用。下面介绍Linux调用动态库经常使用的函数,但在使用动态库时,源程序必须包含dlfcn.h头文件,该文件定义调用动态链接库的函数的原型。(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);dlopen
16、用于打开指定名字(filename)的动态链接库,并返回操作句柄。(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol);dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(v
17、oid); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。在取到函数执行地址后,就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。在编写调用动态库的程序的makefile文件时,需要加入编译选项-rdynamic和-ldl。除了采用这种方式编写和调用动态库之外,Linux操作系统也提供了一种更为方便的动态库调用方式,也方便了其它程序调用,这种方式与Windows 系统的隐式链接类似。其动态库命名方式为“”3、两种系统动态库比较分析Windows和Linux采用动态链接库技术目的是基本一致的,但由于操作系统的不
18、同,他们在许多方面还是不尽相同,下面从以下几个方面进行阐述。(1)动态库程序编写,在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数作为初始化的人口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。Linux下的gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要到函数做特别声明,编写比较方便。(2)动态库编译,在windows系统下面,有方便的调试编译环境,通常不用自己去编写makefile文件,但在linux下面,需要自己动手去编写makefile文件,因此,必须掌握一定的makefile编写技巧,另外,通常Linux编译规则相对严格。(3)动态库调用方面,Windows和Linux对其下编制的动态库都可以采用显式调用或隐式调用,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《机械设计基础 》课件-第9章
- 2024-2025学年年八年级数学人教版下册专题整合复习卷14.1.2 函数(含答案)
- 联通述职报告范文
- 工作检查报告范文
- 2025年天津a2货运从业资格证考试
- 2025年那曲货运从业资格证考题
- 2025年三门峡普通货运从业资格证模拟考试
- 2025年石家庄货运从业资格证模拟试题及答案大全
- 2025年遵义货运从业资格考试
- 2025年鄂尔多斯货运从业资格考题
- 福建百校2025届高三12月联考历史试卷(含答案解析)
- 2024年山西省建筑安全员《B证》考试题库及答案
- 2023年益阳市安化县招聘乡镇卫生院护理人员笔试真题
- 《基于PLC的智能交通灯控制系统设计》10000字(论文)
- 首都经济贸易大学《微积分》2021-2022学年第一学期期末试卷
- 人音版音乐七年级上册《父亲的草原母亲的河》课件
- 2024年度短视频内容创作服务合同3篇
- 2024年度拼多多店铺托管经营合同2篇
- 介入治疗并发症
- 2023年北京肿瘤医院(含社会人员)招聘笔试真题
- 能源管理总结报告
评论
0/150
提交评论