何时应该使用dlopen()?dlopen()是什么意思,是动态加载吗?

8

我已经阅读了下面的链接,通过这个链接我理解了如何创建和使用共享库。 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

然而,我有几个问题:

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

提前感谢。


相关:https://dev59.com/eGkw5IYBdhLWcg3wNn6h - Daniel
1个回答

10

动态库

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

共享库的载入有两种方式:

  1. 动态链接库

在此情况下,程序已经与共享库链接,内核在执行时(如果该库尚未在内存中)加载该库。在链接对此进行了解释。

  1. 动态装载库

对于创建“插件”架构很有用。如其名称所示,动态装载是关于按需装载库和在执行期间链接它。程序通过调用带有该库的函数来完全控制操作。 使用 dlopen()、dlsym() 和 dlclose() 来完成此操作。dlopen() 函数打开一个库并为其做好准备使用。 通过该系统调用,可以在无需链接的情况下打开共享库并使用其中的功能。当程序发现需要使用特定库的函数时,就可以调用 dlopen() 打开该库。如果该库在系统上不可用,则该函数将返回 NULL,并由您处理。您可以使程序终止。

DL 示例: 此示例加载数学库并打印2.0的余弦值,并在每个步骤检查错误(建议如此):

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char **argv) {
    void *handle;
    double (*cosine)(double);
    char *error;

    handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
    if (!handle) {
        fputs (dlerror(), stderr);
        exit(1);
    }

    cosine = dlsym(handle, "cos");
    if ((error = dlerror()) != NULL)  {
        fputs(error, stderr);
        exit(1);
    }

    printf ("%f\n", (*cosine)(2.0));
    dlclose(handle);
}

在编译动态链接库的源代码时,请使用-rdynamic选项。
例如:gcc -rdynamic -o progdl progdl.c -ldl。

这个在提到的链接里有解释。实际上我并没有看到任何链接。 - John
1
@John,链接在问题的开头。 - Irfan Latif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接