【发布时间】: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