深入分析Windows和Linux动态库应用异同

2008-02-23 05:40:43来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

摘要:动态链接库技术实现和设计程式常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库能够有效的减少程式大小,节省空间,提高效率,增加程式的可扩展性,便于模块化管理。

但不同操作系统的动态库由于格式 不同,在需要不同操作系统调用时需要进行动态库程式移植。本文分析和比较了两种操作系统动态库技术,并给出了将Visual C 编制的动态库移植到Linux上的方法和经验。

1、引言

动态库(Dynamic Link Library abbr,DLL)技术是程式设计中经常采用的技术。其目的减少程式的大小,节省空间,提高效率,具备很高的灵活性。

采用动态库技术对于升级软件版本更加容易。和静态库(Static Link Library)不同,动态库里面的函数不是执行程式本身的一部分,而是根据执行需要按需载入,其执行代码能够同时在多个程式中共享。

在Windows和Linux操作系统中,都可采用这种方式进行软件设计,但他们的调用方式连同程式编制方式不尽相同。本文首先分析了在这两种操作系统中通常采用的动态库调用方法连同程式编制方式,然后分析比较了这两种方式的不同之处,最后根据实际移植程式经验,介绍了将VC 编制的Windows动态库移植到Linux下的方法。

2、动态库技术

2.1 Windows动态库技术

动态链接库是实现Windows应用程式共享资源、节省内存空间、提高使用效率的一个重要技术手段。常见的动态库包含外部函数和资源,也有一些动态库只包含资源,如Windows字体资源文档,称之为资源动态链接库。通常动态库以.dll,.drv、.fon等作为后缀。

相应的windows静态库通常以.lib结尾,Windows自己就将一些主要的系统功能以动态库模块的形式实现。

Windows动态库在运行时被系统加载到进程的虚拟空间中,使用从调用进程的虚拟地址空间分配的内存,成为调用进程的一部分。DLL也只能被该进程的线程所访问。DLL的句柄能够被调用进程使用;调用进程的句柄能够被DLL使用。

DLL模块中包含各种导出函数,用于向外界提供服务。DLL能够有自己的数据段,但没有自己的堆栈,使用和调用他的应用程式相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制和具体的编程语言及编译器无关,能够通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用他的线程或进程任何。

根据调用方式的不同,对动态库的调用可分为静态调用方式和动态调用方式。

(1)静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程式结束时DLL卸载的编码(Windows系统负责对DLL调用次数的计数),调用方式简单,能够满足通常的需要。通常采用的调用方式是把产生动态连接库时产生的.LIB文档加入到应用程式的工程中,想使用DLL中的函数时,只须在源文档中声明一下。

LIB文档包含了每一个DLL导出函数的符号名和可选择的标识号连同DLL文档名,不含有实际的代码。Lib文档包含的信息进入到生成的应用程式中,被调用的DLL文档会在应用程式加载时同时加载在到内存中。

(2)动态调用,即显式调用方式,是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,比较复杂,但能更加有效地使用内存,是编制大型应用程式时的重要方式。在Windows系统中,和动态库调用有关的函数包括:

①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。

②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。

③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。

在windows中创建动态库也很方便和简单。在Visual C 中,能够创建不用MFC而直接用C语言写的DLL程式,也能够创建基于MFC类库的DLL程式。每一个DLL必须有一个入口点,在VC 中,DllMain是个缺省的入口函数。DllMain负责初始化(Initialization)和结束(Termination)工作。

动态库输出函数也有两种约定,分别是基于调用约定和名字修饰约定。DLL程式定义的函数分为内部函数和导出函数,动态库导出的函数供其他程式模块调用。通常能够有下面几种方法导出函数:

①采用模块定义文档的EXPORT部分指定要输入的函数或变量。

②使用MFC提供的修饰符号_declspec(dllexport)。

③以命令行方式,采用/EXPORT命令行输出有关函数。

在windows动态库中,有时需要编写模块定义文档(.DEF),他是用于描述DLL属性的模块语句组成的文本文档。

2.2 Linux共享对象技术

在Linux操作系统中,采用了很多共享对象技术(Shared Object),虽然他和Windows里的动态库相对应,但他并不称为动态库。相应的共享对象文档以.so作为后缀,为了方便,在本文中,对该概念不进行专门区分。Linux系统的/lib连同标准图像界面的/usr/X11R6/lib等目录里面,就有许多以so结尾的共享对象。

同样,在Linux下,也有静态函数库这种调用方式,相应的后缀以.a结束。Linux采用该共享对象技术以方便程式间共享,节省程式占有空间,增加程式的可扩展性和灵活性。Linux还能够通过LD-PRELOAD变量让研发人员能够使用自己的程式库中的模块来替换系统模块。

同Windows系统相同,在Linux中创建和使用动态库是比较容易的事情,在编译函数库源程式时加上-shared选项即可,这样所生成的执行程式就是动态链接库。通常这样的程式以so为后缀,在Linux动态库程式设计过程中,通常流程是编写用户的接口文档,通常是.h文档,编写实际的函数文档,以.c或.cpp为后缀,再编写makefile文档。对于较小的动态库程式能够不用如此,但这样设计使程式更加合理。

编译生成动态连接库后,进而能够在程式中进行调用。在Linux中,能够采用多种调用方式,同Windows的系统目录(..\system32等)相同,能够将动态库文档拷贝到/lib目录或在/lib目录里面建立符号连接,以便任何用户使用。

下面介绍Linux调用动态库经常使用的函数,但在使用动态库时,源程式必须包含dlfcn.h头文档,该文档定义调用动态链接库的函数的原型。

(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag); dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。

(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol); dlsym根据动态链接库操作句柄(handle)和符号(symbol),返回符号对应的函数的执行代码地址。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C 箴言:谨慎考虑资源管理类的拷贝行为

下一篇: C 箴言:防止因异常而离开析构函数