【问题标题】:Is there any linker flag that tells to defer the loading of dynamic library after dlopen [duplicate]是否有任何链接器标志告诉在 dlopen 之后推迟加载动态库 [重复]
【发布时间】:2017-01-22 21:18:36
【问题描述】:

我有以下代码

  1. 文件hello.cc

    static A dummyl;
    
    A:: A() {
        fun();
    }
    
    void A::fun() {
        int y = 10;
        int z = 20; 
        int x = y + z;
    }   
    
  2. 文件hello.h

    class A {
      public:
        A a;
        void fun();
    };
    
  3. 文件main.cc

    #include <dlfcn.h>
    #include "hello.h"
    
    typedef void (*pf)();
    int main() {
        void *lib;
        pf greet;
        const char * err;
        printf("\n Before dlopen\n");
        lib = dlopen("libhello.so", RTLD_NOW | RTLD_GLOBAL);
        if (!lib) {
            exit(1);
        }
        A *a = new A ;
        a->fun();
        dlerror(); /*first clear any previous error; redundant in this case but a useful habit*/
        dlclose(lib); 
        return 0;
    }
    

构建阶段:

  1. g++ -fPIC -c hello.cc
  2. g++ -shared -o libhello.so hello.o
  3. g++ -o myprog main.cc -ldl -L。 -lhello

由于我在实际情况下的共享库是 libQtCore.so ,我需要在链接器中使用 -lQtCore 来链接它,因为我不能直接使用符号,并且因为有很多函数,所以 libQtCore,实际上不建议为 libQtCore.so

的每个函数使用 dlysym

由于我链接,我的静态全局变量在 dlopen 之前被初始化。链接器 g++ 是否有任何标志告诉编译器仅在 _dlopen _ 之后加载共享库?

【问题讨论】:

  • 您遗漏了一些基本概念。一旦代码被编译,编译器就完全不在了。在运行时“加载共享库”的不是编译器。此外,库要么链接到可执行文件,要么不链接到可执行文件。如果它是链接的,它会在运行时加载。如果没有,则没有,可以使用 dlopen() 加载。结束。 “直到 dlopen 才加载库”的概念没有意义。这正是 dlopen() 所做的:它加载一个没有直接链接到可执行文件的库。
  • 您能否指出我可以看到在运行时使用 dlopen 或链接共享库加载共享库的确切差异的文档
  • Here 可能会有所帮助。
  • 我发现here 的解释很有帮助。

标签: c++ qt gcc linker shared-libraries


【解决方案1】:

链接器 g++ 是否有任何标志告诉编译器仅在 _dlopen _ 之后加载共享库?

是的。在 Windows 上。它被称为延迟加载。它在 Linux/OS X 上不存在。可以实现它,但需要对 binutils 和 ld.so 进行修改。有关这方面的一些背景信息,请参阅 this article

但你不需要关心任何。真的。

您正面临一个众所周知的问题。众所周知,它甚至还有一个名字:The Static Initialization Order Fiasco

解决所有问题的方法很简单:不要像以前那样使用静态全局变量。

要修复它,请使用Q_GLOBAL_STATIC,或自己重新实现类似的东西。这样,值将在第一次使用时构建,而不是过早地构建。仅此而已。

旁注:您最近的问题因成为XY Problem 而受到严重影响。您正在尝试为一个相当简单的问题想出各种 Rube Goldberg 式的解决方案,您花了一周多的时间才最终泄露。不要询问潜在的解决方案,而要询问潜在的问题是您正在尝试解决的问题。所有加载库的东西都完全和与您的问题无关,您根本不需要关心它。

【讨论】:

    猜你喜欢
    • 2018-03-22
    • 2023-03-13
    • 2020-11-28
    • 2016-05-07
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    相关资源
    最近更新 更多