大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C++技巧 > 深入分析Windows和Linux动态库应用异同

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

关键词:WindowsLinux  阅读(762) 赞(14)

[摘要]本文主要是对深入分析Windows和Linux动态库应用异同的讲解,希望对您学习C++有所帮助!
静态链接库技术完成和设计顺序常用的技术,在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),前往符号对应的函数的执行代码地址。

(3)封锁静态链接库:dlclose,函数原型为: int dlclose (void *handle); dlclose用于封锁指定句柄的静态链接库,只需当此静态链接库的运用计数为0时,才会真正被系统卸载。

(4)静态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当静态链接库操作函数执行失败时,dlerror可以前往出错信息,前往值为NULL时表示操作函数执行成功。

在取到函数执行地址后,就可以在静态库的运用顺序里面根据静态库提供的函数接口声明调用静态库里面的函数。在编写调用静态库的顺序的makefile文件时,需求参与编译选项-rdynamic和-ldl。

除了采用这种方式编写和调用静态库之外,Linux操作系统也提供了一种更为方便的静态库调用方式,也方便了其它顺序调用,这种方式与Windows系统的隐式链接类似。其静态库命名方式为“lib*.so.*”。在这个命名方式中,第一个*表示静态链接库的库名,第二个*通常表示该静态库的版本号,也可以没有版本号。

在这种调用方式中,需求维护静态链接库的配置文件/etc/ld.so.conf来让静态链接库为系统所运用,通常将静态链接库所在目录名追加到静态链接库配置文件中。如具有X window窗口系统发行版该文件中都具有/usr/X11R6/lib,它指向X window窗口系统的静态链接库所在目录。

为了使静态链接库能为系统所共享,还需运转静态链接库的管理命令./sbin/ldconfig。在编译所引用的静态库时,可以在gcc采用 –l或-L选项或直接引用所需的静态链接库方式中止编译。在Linux里面,可以采用ldd命令来反省顺序依赖共享库。

3、两种系统静态库比较分析

Windows和Linux采用静态链接库技术目的是基本分歧的,但由于操作系统的不同,他们在许多方面还是不尽相反,下面从以下几个方面中止阐述。

(1)静态库顺序编写,在Windows系统下的执行文件格式是PE格式,静态库需求一个DllMain函数作为初始化的人口,通常在导出函数的声明时需求有_declspec(dllexport)关键字。Linux下的gcc编译的执行文件默许是ELF格式,不需求初始化入口,亦不需求到函数做特别声明,编写比较方便。

(2)静态库编译,在windows系统下面,有方便的调试编译环境,通常不用自己去编写makefile文件,但在linux下面,需求自己动手去编写makefile文件,因此,必需掌握一定的makefile编写技巧,另外,通常Linux编译规则相对严峻。

(3)静态库调用方面,Windows和Linux对其下编制的静态库都可以采用显式调用或隐式调用,但详细的调用方式也不尽相反。

(4)静态库输出函数反省,在Windows中,有许多工具和软件可以中止反省DLL中所输出的函数,例如命令行方式的dumpbin以及VC++工具中的DEPENDS顺序。在Linux系统中通常采用nm来反省输出函数,也可以运用ldd反省顺序隐式链接的共享对象文件。

(5)对操作系统的依赖,这两种静态库运转依赖于各自的操作系统,不能跨平台运用。因此,关于完成相反功用的静态库,必需为两种不同的操作系统提供不同的静态库版本。

4、静态库移植方法

假定要编制在两个系统中都能运用的静态链接库,通常会先选择在Windows的VC++提供的调试环境中完成初始的开发,毕竟VC++提供的图形化编辑和调试界面比vi和gcc方便许多。完成测试之后,再中止静态库的顺序移植。

通常gcc默许的编译规则比VC++默许的编译规则严峻,即使在VC++下面没有任何警告错误的顺序在gcc调试中也会出现许多警告错误,可以在gcc中采用-w选项封锁警告错误。

下面给出顺序移植需求遵照的规则以及阅历。

(1)尽量不要改动原有静态库头文件的顺序。通常在C/C++言语中,头文件的顺序有相当的关系。另外虽然C/C++言语区分大小写,但在包括头文件时,Linux必需与头文件的大小写相反,由于ext2文件系统对文件名是大小写敏感,否则不能正确编译,而在Windows下面,头文件大小写可以正确编译。

(2)不同系统独有的头文件。在Windows系统中,通常会包括windows.h头文件,假定调用底层的通讯函数,则会包括winsock..h头文件。因此在移植到Linux系统时,要注释掉这些Windows系统独有的头文件以及一些windows系统的常量定义说明,添加Linux都底层通讯的支持的头文件等。

(3)数据类型。VC++具有许多独有的数据类型,如__int16,__int32,TRUE,SOCKET等,gcc编译器不支持它们。通常做法是需求将windows.h和basetypes.h中对这些数据中止定义的语句复制到一个头文件中,再在Linux中包括这个头文件。例如将套接字的类型为SOCKET改为int。

(4)关键字。VC++中具有许多标准C中所没有采用的关键字,如BOOL,BYTE,DWORD,__asm等,通常在为了移植方便,尽量不运用它们,假定真实无法避免可以采用#ifdef 和#endif为LINUX和WINDOWS编写两个版本。

(5)函数原型的修正。通常假定采用标准的C/C++言语编写的静态库,基本上不用再重新编写函数,但关于系统调用函数,由于两种系统的区别,需求改动函数的调用方式等,如在Linux编制的网络通讯静态库中,用close()函数替代windows操作系统下的closesocket()函数来封锁套接字。另内在Linux下没有文件句柄,要翻开文件可用open和fopen函数,详细这两个函数的用法可参考文献[2]。

(6)makefile的编写。在windows下面通常由VC++编译器来担任调试,但gcc需求自己动手编写makefile文件,也可以参照VC++生成的makefile文件。关于静态库移植,编译静态库时需求参与-shared选项。关于采用数学函数,如幂级数的顺序,在调用静态库是,需求参与-lm。

(7)其它一些需求留意的地方

①顺序设计结构分析,关于移植它人编写的静态库顺序,顺序结构分析是必不可少的步骤,通常在静态库顺序中,不会包括界面等操作,所以相对容易一些。

②在Linux中,对文件或目录的权限分为拥有者、群组、其它。所以在存取文件时,要留意对文件是读还是写操作,假定是对文件中止写操作,要留意修注释件或目录的权限,否则无法对文件中止写。

③指针的运用,定义一个指针只给它分配四个字节的内存,假定要对指针所指向的变量赋值,必需用malloc函数为它分配内存或不把它定义为指针而定义为变量即可,这点在linux下面比windows编译严峻。异常结构不能在函数中传值,假定要在函数中中止结构传值,必需把函数中的结构定义为结构指针。

④途径标识符,在Linux下是“/”,在Windows下是“\”,留意windows和Linux的对静态库搜索途径的不同。

⑤编程和调试技巧方面。对不同的调试环境有不同的调试技巧,在这里不多叙说。

5、终了语

本文系统分析了windows和Linux静态库完成和运用方式,从顺序编写、编译、调用以及对操作系统依赖等方面综合分析比较了这两种调用方式的不同之处,根据理论顺序移植阅历,给出了将VC++编制的Windows静态库移植到Linux下的方法以及需求留意的效果,同时并给出了顺序示例片断,理论在顺序移植进程中,由于系统的设计等方面,可以移植起来需求留意的方面远比上面复杂,本文经过总结归结进而为不同操作系统顺序移植提供了有意的阅历和技巧。


相关评论