gpt4 book ai didi

c++ - 从相应的 dlopen() 加载的代码中调用 dlclose() 可以吗?

转载 作者:行者123 更新时间:2023-12-04 09:31:52 24 4
gpt4 key购买 nike

题目如题,背景如下:
在 Linux 上,我正在尝试使用 dlopen() 等来构建具有最小和干净界面的 C++ .so 插件框架。这意味着:

  • 加载插件并从插件创建 (C++) 单例对象只需调用函数 makePluginObject()带有正在加载的 .so 文件的路径并返回指向该对象的指针。在后台,此函数调用 dlopen(),然后是实际的对象分配和构造。该对象属于 C++ 类,其实现在 .so 中。
  • 之后,用户只需删除(调用 dtor)指针即可完成所有必要的清理工作,包括由 dtor 完成的 dlclose()。这将通过在对象的 dtor 中调用 dlclose() 来实现。 (在幕后,来自 dlopen() 的句柄在 makePluginObject() 期间被传递给对象。)至关重要的是,没有额外的关闭/拆卸函数供用户显式调用。

  • 上面的设计可能意味着调用 dlclose() 的代码在被 dlopen'ed 的 .so 中。关键问题是:代码可以自行调用 dlclose() 吗?我想知道,因为 dlclose() 的幼稚实现会从内存中取消映射在对象销毁期间仍在运行的代码。
    重要的是用户界面保持如此简单。用户只需调用 makePluginObject()并在完成后删除结果指针。如果引入了一个teardown函数,用户在删除对象后必须显式调用,那么界面就重了很多,用户的负担也大了很多。如果允许明确的拆卸功能,我知道该怎么做,而这个问题与该用例无关。
    在我的实验中,没有崩溃,但似乎 dlclose() 并没有真正做任何事情,因为 valgrind 报告了很多与我对 dlopen() 的调用相关的可访问内存。

    最佳答案

    是的,调用dlclose由于您指定的原因,来自库函数将出现段错误:

    $ cat main.c
    #include <dlfcn.h>
    int main() {
    void *h = dlopen("./liblib.so", RTLD_LAZY | RTLD_GLOBAL);
    int (*foo)(void *) = dlsym(h, "foo");
    foo(h);
    return 0;
    }
    [y.gribov@link ~]$ cat lib.c
    #include <dlfcn.h>
    #include <stdio.h>
    int foo(void *h) {
    printf("Before dlclose\n");
    dlclose(h);
    printf("After dlclose\n");
    return 10;
    }
    $ gcc main.c -ldl
    $ gcc -o liblib.so lib.c -shared -fPIC -ldl
    $ ./a.out
    Before dlcose
    Segmentation fault
    目前尚不清楚为什么它在您的特定情况下有效(您的库可能会导出 GNU_UNIQUE 符号,库可能会被 dlopen 编辑两次,等等)。

    关于c++ - 从相应的 dlopen() 加载的代码中调用 dlclose() 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62806477/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com