Linux C++ g++ -ldl编译参数(链接libdl.so动态库,头文件<dlfcn.h>)(Dynamic Linker的缩写)(混链接混合链接)

Posted Dontla

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux C++ g++ -ldl编译参数(链接libdl.so动态库,头文件<dlfcn.h>)(Dynamic Linker的缩写)(混链接混合链接)相关的知识,希望对你有一定的参考价值。

文章目录

-ldl是什么?

-ldl 是 g++ 编译器链接选项,它会将动态链接库 libdl.so 链接进可执行文件中,以便程序可以调用 libdl 中定义的函数。

libdl是一个操作系统级别的库(不是C++标准库也不知第三方库,它由操作系统提供),用于在程序运行时动态地加载共享对象文件(shared object),并获取其中定义的符号(symbol)并进行调用。在 Linux 系统中,通过调用 dlopen、dlsym 等函数来实现动态库加载和符号查找。它并不是 C++ 标准库的一部分,而是 POSIX 标准(Portable Operating System Interface)的一部分,是在 UNIX 和类 UNIX 系统中广泛使用的动态库。

在使用 libdl 中的函数时,需要在程序中包含 <dlfcn.h> 头文件,并链接 libdl 库。编译时使用 -ldl 参数可以告诉编译器将 libdl 库链接到可执行文件中,使程序能够调用 libdl 中的函数。

为什么头文件不叫dl.h或者动态库文件不叫libdlfcn.so?

dlfcn.h 头文件是用于使用动态链接库的函数的标准头文件,而 dlopen,dlsym,dlclose 等函数是实际的函数符号,它们在 Unix 系统上定义在 libdl.so 库文件中。因此,在编译时需要将链接器指向 libdl.so 库文件,这样编译器才能找到这些函数的实现。而 libdl.so 的名称来自于 “Dynamic Linker” 的缩写。

至于为什么 dlfcn.h 没有叫做 dl.h,或者 libdl.so 没有叫做 libdlfcn.so,这可能是由于历史原因。在最初的 Unix 系统中,动态链接库的概念并不是一个标准的操作系统特性,而是由每个厂商根据自己的需求实现的。这就导致了不同厂商实现的动态链接库存在差异。在后来的标准化过程中,一些函数和库被标准化,但名称并没有改变,以保持与现有的实现兼容。因此,在 Unix 系统中,有些库和头文件的名称可能看起来有些奇怪,但是它们仍然被广泛使用。

如何链接libdl.a静态库?

-ldl是用来链接动态库libdl.so的,它是一个动态库链接选项。当你编译链接的时候,指定了-ldl,它会告诉编译器去链接libdl.so动态库。

如果你要链接静态库libdl.a,则需要使用静态库链接选项-ldl,例如gcc program.c -o program -ldl -static。这里的-static选项表示链接静态库,如果不指定-static选项,则默认链接动态库。

总之,-ldl选项是用来链接动态库的,不管是libdl.so还是libdl.a。

如果g++编译时既需要链接静态库ldl,又需要链接动态库lxx,指令该怎么写?(混链接)

-ldl是默认链接动态库。当使用-l选项指定库时,链接器将首先尝试链接动态库,如果无法找到动态库,则尝试链接静态库。所以在大多数情况下,-ldl将链接动态库libdl.so,而不是静态库libdl.a。

不过如果你想链接静态库,可以使用-l选项和完整的静态库文件名来链接静态库,例如:-l:libdl.a。这会指示链接器链接静态库文件libdl.a。(没试过)

参考文章:gcc/g++ 静态动态库 混链接.

另外,貌似还有一种方式:

g++ your_program.cpp -o your_program -ldl -Wl,-Bstatic -lxx -Wl,-Bdynamic

同时链接静态库 libdl.a 和动态库 libxx.so

其中,-Wl,-Bstatic 表示后面的库需要静态链接,-Wl,-Bdynamic 表示后面的库需要动态链接。

-Wl是告诉编译器把后面的参数传递给链接器(ld)。因为在编译 C++ 程序的时候,编译器(g++)调用了一个叫链接器(ld)的程序,它的作用是把各种对象文件、库文件链接在一起,生成可执行文件。
-Wl就是为了把编译器的参数传递给链接器,相当于直接传递给链接器一样,其后的参数都是传递给链接器的选项。例如,-Wl,-rpath-link,-Wl,-Bdynamic等选项,都是用来控制链接器行为的选项。

以上是关于Linux C++ g++ -ldl编译参数(链接libdl.so动态库,头文件<dlfcn.h>)(Dynamic Linker的缩写)(混链接混合链接)的主要内容,如果未能解决你的问题,请参考以下文章

linux (g++) 上的分段错误,但 Mac OS 上没有。?

[C++][linux]linux C++获取mac地址

c++ segfault 在一个平台(MacOSX)但不是另一个(Linux)

linux下编译c++程序

在 Linux 上链接 c++ 库

开启 C++ 生活 -- 第一个 C++ 程序