BandMan home

分析Windows和Linux动态库

采用动态库的方式进行软件设计,但它们的调用方式以及程序编制方式不尽相同。

windows的动态库技术

动态链接库是实现Windows应用程序共享资源、节省内存空间、提高使用效率的一个重要技术。

windows动态库在运行时被系统加载到进程的虚拟空间中,称为调用进程的一部分。DLL的句柄可以被调用进程使用。一个dll在内存中只有一个实例。DLL的编制与具体的语言及编译器无关。

动态库的调用方式有两种,一是静态调用,二是动态调用

Linux共享对象技术

Linux采用该共享对象技术以方便程序间共享,节省程序占有空间,增加程序的可扩展性和灵活性。

在Linux动态库程序设计过程中,通常流程是编写用户的接口文件,通常是.h文件,编写实际的函数文件,以.c或.cpp为后缀,再编写makefile文件。

在取到函数执行地址后,就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。在编写调用动态库的程序的makefile文件时,需要加入编译选项-rdynamic和-ldl。

OS不同导致的动态链接库技术的一点不同

(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)对操作系统的依赖,这两种动态库运行依赖于各自的操作系统,不能跨平台使用。因此,对于实现相同功能的动态库,必须为两种不同的操作系统提供不同的动态库版本。

动态库移植方法

  1. 尽量不改变动态库头文件的顺序
  2. 不同系统独有的头文件。如windows.h,如果调用底层通信函数,则会包含winsock.h,因此在移植到Linux系统时,要注释掉独有的头文件,以及常量定义说明,增加Linux独有的同样功能头文件
  3. 数据类型。独有的数据类型__int16, __int32, TRUE, SOCKET等gcc编译器并不支持。通常做法是将独有头文件中含有数据定义的语句复制到另一个头文件中,再在Linux中包含这个头文件。例如将SOCKET类型改为int
  4. 关键字。BOOL, BYTE, DWORD, __asm等,需采用#ifdef和#endif来编写两个版本的关键字
  5. 函数原型的修改。对于系统调用函数,需要改变函数的调用方式。如Linux编制的网络通信动态库中,用close()函数代替windows系统的closesocket()函数来关闭套接字。另外Linux没有文件句柄,要打开文件可用open和fopen函数。
  6. makefile的编写。
Fork me on GitHub