何时实际使用 dlopen()?dlopen() 是指动态加载吗?

Sat*_*ish 8 linker shared-libraries dynamic-loading dlopen .so

我浏览了下面的链接,通过它我了解了如何创建和使用共享库。 https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

Step 1: Compiling with Position Independent Code
$ gcc -c -Wall -Werror -fpic foo.c

Step 2: Creating a shared library from an object file
$ gcc -shared -o libfoo.so foo.o

Step 3: Linking with a shared library
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo

Step 4: Making the library available at runtime
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
This is a shared library test...
Hello, I am a shared library
Run Code Online (Sandbox Code Playgroud)

但是,我有几个问题:

  1. 在给定的链接中,没有使用打开共享库所需的 dlopen()。这段代码在没有 dlopen() 调用的情况下如何工作?
  2. 何时实际使用 dlopen()?
  3. 我可以在没有 .so 文件可用的情况下编译程序(程序具有对该共享库的函数调用)吗?
  4. dlopen() 是否意味着动态加载,而上面链接中的示例(步骤 3)是否意味着静态加载?如果是,那么在动态加载的情况下,链接步骤(步骤3)有什么区别吗?

提前致谢。

Sat*_*ish 12

动态库

\n

当我们将应用程序链接到共享库时,链接器会留下一些存根(未解析的符号)以在应用程序加载时填充。这些存根需要在运行时或应用程序加载时由称为动态链接器的工具填充。

\n

共享库的加载有两种类型,

\n
    \n
  1. 动态链接库\xe2\x80\x93
  2. \n
\n

这里,程序与共享库链接,内核在执行时加载该库(如果它\xe2\x80\x99s不在内存中)。\n这在提到的链接中进行了解释。

\n
    \n
  1. 动态加载库\xe2\x80\x93
  2. \n
\n

对于创建“插件”架构很有用。\n顾名思义,动态加载是指按需加载库并在执行期间链接。\n程序通过调用库函数来实现完全控制。\n这是使用 dlopen 完成的()、dlsym()、dlclose()。\ndlopen() 函数打开一个库并准备使用它。\n通过此系统调用,可以打开共享库并使用其中的函数,而无需链接用它。你的程序刚刚启动,当它发现需要使用特定库中的函数时,它会调用 dlopen() 打开该库。如果该库在系统上不可用,则该函数将返回 NULL,并且由您(程序员)来处理。你可以让程序优雅地结束。

\n

DL 示例:\n此示例加载数学库并打印 2.0 的余弦,并在每一步检查错误(推荐):

\n
#include <stdlib.h>\n#include <stdio.h>\n#include <dlfcn.h>\n\nint main(int argc, char **argv) {\n    void *handle;\n    double (*cosine)(double);\n    char *error;\n\n    handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);\n    if (!handle) {\n        fputs (dlerror(), stderr);\n        exit(1);\n    }\n\n    cosine = dlsym(handle, "cos");\n    if ((error = dlerror()) != NULL)  {\n        fputs(error, stderr);\n        exit(1);\n    }\n\n    printf ("%f\\n", (*cosine)(2.0));\n    dlclose(handle);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译 DL 源代码时使用 -rdynamic。

\n

前任。gcc -rdynamic -o progdl progdl.c -ldl

\n