【问题标题】:in gcc how to force symbol resolution at runtime在 gcc 中如何在运行时强制符号解析
【发布时间】:2010-07-01 12:52:48
【问题描述】:

我在这个网站上的第一篇文章充满希望:: 我正在尝试使用 gcc 来理解静态链接、动态链接、共享库、静态库等。每次我尝试深入研究这个主题时,我都有一些我不太了解的东西。

一些动手工作:

bash$ cat main.c

#include "printhello.h"
#include "printbye.h"

void main()
{
PrintHello();
PrintBye();
}

bash$ cat printhello.h
void PrintHello();

bash$ cat printbye.h
void PrintBye();

bash$ cat printbye.c
#include <stdio.h>

void PrintBye()
{
printf("Bye bye\n");
}

bash$ cat printhello.c
#include <stdio.h>

void PrintHello()
{
printf("Hello World\n");
}

gcc -Wall -fPIC -c *.c -I.
gcc -shared -Wl,-soname,libcgreet.so.1 -o libcgreet.so.1.0   *.o
ln -sf libcgreet.so.1.0 libcgreet.so
ln -sf libcgreet.so.1.0 libcgreet.so.1

所以我创建了一个共享库。 现在我想将此共享库与我的主程序链接以创建可执行文件。

gcc -Wall -L. main.c -lcgreet -o greet

它工作得很好,如果我在运行 greet 之前设置 LD_LIBRARY_PATH(或将它与 rpath 选项链接),我可以让它工作。

我的问题是不同的: 由于我无论如何都在使用共享库,因此不可能在运行时强制符号解析(不确定术语,但根据“链接器和加载器”一书可能称为动态链接)。我知道我们可能不想这样做,因为这会使程序运行缓慢并且每次我们想要运行程序时都会产生开销,但我试图理解这一点以清除我的概念。

gcc 链接器是否提供任何选项来在运行时延迟符号解析? (使用我们实际运行程序的库来实现)(因为如果库中有任何更改,编译时可用的库可能与运行时可用的库不同) 我希望能够做某事:

bash$ gcc main.c -I.

(这里需要什么选项?) 这样我就不必提供库名称,只需告诉它我想在运行时进行符号解析,因此标题现在已经足够好了,不需要实际的库名称。

谢谢, 永远的学习者。

【问题讨论】:

  • 确保使用适当的语言标记问题。它被标记为 c++,但代码是 C。请注意,为了能够使用纯动态库加载 C++ 中的代码,需要包含额外的 extern "C",而这些在 C 中是不需要的,也不是有效的。

标签: c++ gcc linker compilation


【解决方案1】:

任何链接器(gccld 或任何其他)仅在编译时解析链接。那是因为 ELF 标准(与大多数其他标准一样)没有像您描述的那样定义“运行时”链接。它们要么静态链接(即 lib.a),要么在启动时链接(lib.so,加载 ELF 时必须存在)。但是,如果您使用动态链接,链接器只会在 ELF 中放入文件名和它必须找到的符号,它不会直接链接文件。所以,如果你以后想升级lib到更新的版本,你可以这样做,只要系统能找到相同的文件名(路径实际上可以不同)和相同的符号名。

在运行时获取符号的另一个选项是使用dlopen,这与gccld 无关。 dlopen 简单地说,打开一个动态链接库,就像fopen 可能一样,并返回一个句柄,然后你将它传递给dlsym,并带有你想要的符号名称,例如函数名称.然后dlsym 将向您传递一个指向该符号的指针,然后您可以使用它来调用函数或用作变量。这就是插件的实现方式。

【讨论】:

  • 如果 C++ 语言标签正确,请记住将符号标记为extern "C",以免它们在编译时被损坏。
【解决方案2】:

我认为您正在寻找 ld 选项“--unresolved-symbols=ignore-all”,是的,它实际上可以做到(忽略上一个答案)。想象一下共享库加载较晚的场景(当程序已经运行时),它可以使用主进程已经解析/加载的所有符号,无需费心再做一次。顺便说一句,它不会毫不犹豫地让它变慢,至少在 Linux 上是这样

【讨论】:

    猜你喜欢
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2011-04-21
    • 1970-01-01
    • 2014-04-24
    相关资源
    最近更新 更多