【问题标题】:Delay-Load equivalent in unix based systems基于 unix 的系统中的延迟负载等效
【发布时间】:2011-02-26 18:56:37
【问题描述】:

在基于 unix 的系统中,延迟负载是什么。

我有一个代码foo.cpp,在使用 gcc 编译时,我将它链接到共享对象(总共有三个 .so 文件。)。每个.so 文件都有不同的选项。

./foo -v 需要libversion.so ./foo -update需要libupdate.so

我需要这些库的符号应该只在运行时解析。

./foo -v 不应中断,即使 libupdate.so 库不存在。

它正在使用延迟加载选项(在 dll 的属性中)在 Windows 中工作。它在 unix 系统中的等价物是什么。

-lazy 选项在 UNIX 中的作用是否相同?如果是这样,在哪里包含这个选项:在 makefile 中还是在链接器 ld 中?

【问题讨论】:

  • 5 年后我还想听到这个问题的答案。

标签: c unix object linker shared


【解决方案1】:

请参阅系统上的 dlopen() 参考。您可以在运行时而不是在链接时手动打开库并解析外部符号。

挖出一个例子:

int main(int argc, char **argv) {                 
    void *handle=NULL;                                 
    double (*myfunc)(double);                     
    char *err=NULL;                                  

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

    myfunc = dlsym(handle, "sin");                
    if ((err = dlerror()) != NULL)  {           
        perror(err);
        exit(1);                                  
    }                                             

    printf("sin of 1 is:%f\n", (*myfunc)(1.));              
    dlclose(handle);            
    return 0;                  
}                                                 

【讨论】:

  • 谢谢。但是如果我可以在链接器中指定延迟加载等效选项而不是使用 dlopen 会更好。 GCC 中没有任何选项可以延迟加载 libxxx.so 文件吗?我们可以不使用 gcc -WI 传递延迟加载选项来设置链接器以进行延迟加载吗?链接器会将默认设置为延迟加载吗?请帮助我。在此先感谢
  • 不,使用 dlopen()/dlsym() 是 unix 上的可移植方式。某些系统的自定义链接器可以处理这个问题(例如:docs.sun.com/app/docs/doc/817-1983/6mhm6r4er?l=en&a=view),但 GNU ld 没有这样的选项。
  • @pra 如果您找到一些支持您的声明的文档并将其发布为答案,我会支持它。
  • 可以自动生成dlopen/dlsym 样板(参见其他答案)。
【解决方案2】:

我知道已经 8 年了,但仍然......

GNU 系统不支持延迟加载,但您可以通过创建一个小的静态存根来自己模仿它,该存根提供所有必要的符号和dlopens 在第一次调用时(甚至在程序启动时)的实际实现。这样的存根可以手工编写,通过项目特定的脚本或通过Implib.so tool生成:

# Replace
$ gcc -o foo foo.c -lversion
# with
$ implib-gen.py libversion.so
$ gcc -o foo foo.c libversion.tramp.S libversion.init.c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2021-02-10
    • 2012-04-18
    • 2011-10-22
    • 2013-08-18
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多