Linux 中的应用程序以以下两种方式之一链接到外部函数:要么在构建时与静态库( lib*.a)静态地链接,并且将库代码包含在该应用程序的可执行文件里;要么在运行时与共享库( lib*.so)动态地链接。通过动态链接装入器,将动态库映射进应用程序的可执行内存中。在启动应用程序之前,动态链接装入器将所需的共享目标库映射到应用程序的内存,或者使用系统共享的目标并为应用程序解析所需的外部引用。现在应用程序就可以运行了
在Linux系统中,DLL(动态链接库)被称为共享对象(Shared Objects),通常具有lib*.so的文件格式。这种机制允许程序在运行时加载和使用库,而不是在编译时将其包含在内,从而节省磁盘空间和内存资源。动态链接库在Linux中扮演着重要的角色,特别是对于提供插件功能和应用程序扩展。
了解动态链接的基本概念。当一个Linux应用程序需要使用外部函数时,有两种链接方式:静态链接和动态链接。静态链接是在构建过程中将库代码合并到可执行文件中,而动态链接则是在运行时由动态链接装入器(如ld-linux.so)负责将所需的共享库映射到内存。这样,多个应用程序可以共享同一库的内存副本,减少了系统的内存开销。
例如,一个简单的"Hello World"程序在编译后,可以通过`ldd`命令查看其依赖的共享库。在这个例子中,依赖的是libc.so.6和ld-linux.so.2。动态链接装入器在程序启动前处理这些依赖关系,使程序能够正确运行。
Linux提供了几个关键的API函数来支持动态链接库的加载和管理:
1. `dlopen`:这个函数用于打开一个共享对象文件,并返回一个句柄,以便后续操作。
2. `dlerror`:当发生错误时,此函数会返回一个描述最近错误的ASCII字符串。
3. `dlsym`:通过句柄找到共享对象中的特定符号(函数或变量),并返回一个指向它的指针。
4. `dlclose`:关闭句柄,解除共享对象的映射。
在实际应用中,可以编写一个C程序来演示动态链接库的使用。例如,有一个简单的程序`dlTest`,它首先打印大写的"HeLlO WoRlD",然后通过动态加载`UPPERCASE.so`库,调用其中的函数来改变输出,使其变为全大写。这个过程展示了动态链接库如何在程序运行时改变其行为,实现插件功能。
在动态加载库时,可以使用`dlopen`函数指定库的绝对路径,或者利用`LD_LIBRARY_PATH`环境变量指定的目录进行搜索。此外,系统还会根据`/etc/ld.so.cache`文件中的配置和默认的系统库路径 `/usr/lib` 和 `/lib` 来查找库。
总结来说,Linux中的动态链接库(DLL)机制为程序提供了一种灵活的扩展方式,允许在不修改原始应用程序代码的情况下添加新的功能或更新功能。这使得开发插件、模块化设计以及实现高效资源管理成为可能。通过`dlopen`、`dlsym`等函数,开发者可以直接在运行时动态加载和调用库中的函数,增强了程序的可扩展性和可维护性。