我目前正在尝试了解gcc编译器和链接器的工作原理。我遇到了一种叫做“链接时替代”的技术,我觉得这很有趣。目标是在多个文件中具有多个函数定义,并在链接时确定哪些定义进入最终可执行文件。
一个简单的例子:
main.c中:
#include "header.h"
int main(void)
{
hello("everyone");
return 0;
}
header.h:
#ifndef _HEADER_H
#define _HEADER_H
void hello(const char * name);
#endif
file1.c中:
#include "header.h"
#include <stdio.h>
void hello(const char * name)
{
printf("File1: Hello, %s!\n", name);
}
file2.c中:
#include "header.h"
#include <stdio.h>
void hello(const char * name)
{
printf("File2: Hello, %s!\n", name);
}
现在我有两个问题:
我希望我的问题可以理解;)
谢谢!
答案 0 :(得分:1)
是否可以使用适当的链接顺序选择一个函数(如果所有三个文件都出现在链接器的参数列表中)?
如果通过“所有三个文件”表示目标文件(假设没有弱符号),则不会:所有3个文件都将被链接,并且您将得到重复的符号定义错误。
但是如果你将file1.o放入lib1.a,将file2.o放入lib2.a,那么是:
gcc main.c -l1 -l2 # uses file1.o:hello
gcc main.c -l2 -l1 # uses file2.o:hello
假设file2.c实现了main.c所需的许多功能。是否可以通过使用链接器替换file1.c中不同实现(具有相同名称)的单个函数或某些函数?
是的,但仅限于支持弱符号的平台(例如ELF平台,请参阅__attribute__((weak))
here)。
如果file2.o中的所有符号都是弱定义的,而file1.o中的所有符号都不是,则链接file1.o和file2.o将获得所需的结果:强符号获胜。
我相信(但尚未测试)如果两者 file1.o和file2.o弱定义相同的符号,那么顺序将很重要:
gcc main.c file1.o file2.o # file1.o definitions override file2.o
gcc main.c file2.o file1.o # file2.o definitions override file1.o