xyz*_*xyz 8 c c++ linux linker gcc
这是我在本网站上的第二篇文章,我努力了解与gcc的编译/链接过程.当我尝试生成可执行文件时,需要在链接时解析符号,但是当我尝试创建共享库时,在此库的链接时不会解析符号.当我尝试使用此共享库创建可执行文件时,它们可能会得到解决.动手:
bash$ cat printhello.c
#include <stdio.h>
//#include "look.h"
void PrintHello()
{
look();
printf("Hello World\n");
}
bash$ cat printbye.c
#include <stdio.h>
//#include "look.h"
void PrintBye()
{
look();
printf("Bye bye\n");
}
bash$ cat look.h
void look();
bash$ cat look.c
#include <stdio.h>
void look()
{
printf("Looking\n");
}
bash$ gcc printhello.c printbye.c
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
/tmp/cck21S0u.o: In function `PrintHello':
printhello.c:(.text+0x7): undefined reference to `look'
/tmp/ccNWbCnd.o: In function `PrintBye':
printbye.c:(.text+0x7): undefined reference to `look'
collect2: ld returned 1 exit status
bash$ gcc -Wall -shared -o libgreet printhello.c printbye.c
printhello.c: In function 'PrintHello':
printhello.c:6: warning: implicit declaration of function 'look'
printbye.c: In function 'PrintBye':
printbye.c:5: warning: implicit declaration of function 'look'
Run Code Online (Sandbox Code Playgroud)
所以我的问题是为什么在链接共享库时符号没有得到解决.当我使用这个库来制作可执行文件时,需要完成这项工作(解析其下游的符号),但这意味着我们需要知道这个库在使用这个库时所依赖的内容,但这不是不可取的吗?
谢谢,Jagrati
由于未提供-c(仅编译)选项,因此您要求gcc编译两个源文件,并将它们与标准库(libc)和c运行时启动程序(通常为crt0)链接以产生运行状态程序。crt0尝试通过调用main()进入程序,这是链接器找不到的未定义符号。它找不到它,因为在两个.c文件中都没有main(),对吗?
因此,关于您的实际问题,“为什么在链接时无法解析共享库的符号?” 答案是,“链接时间”是什么意思?根据定义,动态链接程序要在启动之前才“链接”(或者甚至可能不启动,具体取决于您的系统)。
在Linux系统上,您可以使用ldd命令查看程序依赖于哪个动态库(在Mac OS上,请使用“ otool -L”)。ldd的输出将告诉您程序依赖于哪个动态库,在库搜索路径中找到哪些动态库,以及找不到哪些动态库(如果有)。
当您启动动态程序时,链接到其中的动态链接程序将定位并加载程序所依赖的动态库,并将对这些外部符号的引用“修复”。如果这些失败,则您的程序将无法启动。所有以前未解决的符号都已解决,动态链接器返回,C运行时将调用您的main()函数。(在Mac OS上有所不同,但是实际上,链接是在程序启动后发生的。)
| 归档时间: |
|
| 查看次数: |
12197 次 |
| 最近记录: |