gcc:链路时间替换
我目前正试图了解gcc编译器和链接器是如何工作的。我遇到了一种叫做“链接时间替换”的技术,我觉得这很有趣。目标是在多个文件中有一个函数的多个定义,并决定在链接期间哪些定义进入最终可执行文件 一个简单的例子: 主要条款c:gcc:链路时间替换,c,gcc,linker,C,Gcc,Linker,我目前正试图了解gcc编译器和链接器是如何工作的。我遇到了一种叫做“链接时间替换”的技术,我觉得这很有趣。目标是在多个文件中有一个函数的多个定义,并决定在链接期间哪些定义进入最终可执行文件 一个简单的例子: 主要条款c: #include "header.h" int main(void) { hello("everyone"); return 0; } 标题h: #ifndef _HEADER_H #define _HEADER_H void hello(const ch
#include "header.h"
int main(void)
{
hello("everyone");
return 0;
}
标题h:
#ifndef _HEADER_H
#define _HEADER_H
void hello(const char * name);
#endif
文件1.c:
#include "header.h"
#include <stdio.h>
void hello(const char * name)
{
printf("File1: Hello, %s!\n", name);
}
#包括“header.h”
#包括
void hello(常量字符*名称)
{
printf(“文件1:Hello,%s!\n”,名称);
}
文件2.c:
#include "header.h"
#include <stdio.h>
void hello(const char * name)
{
printf("File2: Hello, %s!\n", name);
}
#包括“header.h”
#包括
void hello(常量字符*名称)
{
printf(“文件2:Hello,%s!\n”,名称);
}
现在我有两个问题:
- 是否可以使用适当的链接顺序来选择函数(如果链接器的参数列表中显示了所有三个文件)
- 假设file2.c实现了main.c所需的许多函数。是否可以使用链接器用file1.c中的不同实现(同名)替换单个函数或某些函数?链接器应该首先使用file1.c中的函数定义,然后使用file2.c处理剩余的未解析函数李>
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平台,请参阅\uuuuu属性\((弱))
)
如果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
你能编辑文件2吗?在这种情况下,我会选择以更明确的方式使用的函数。例如,在预处理器开关的帮助下封装在条件部分。与您的问题和问题无关,但以下划线开头并后跟大写字母的符号(如
\u HEADER\u H
)保留在“实现”(编译器和标准库)的所有范围内。是的,我可以编辑文件2。预处理器切换当然是这个问题的解决方案,但我想知道是否有更优雅的方式,也许是通过巧妙地使用链接器(我特别想了解参数的顺序在链接过程中是如何起作用的)。@一些程序员伙计:谢谢你的澄清,我不知道!)可以将一个函数标记为。