【发布时间】:2018-06-15 07:35:53
【问题描述】:
我目前正在尝试了解 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);
}
现在我有两个问题:
- 是否可以通过使用适当的链接顺序来选择函数(如果所有三个文件都出现在链接器的参数列表中)?
- 假设 file2.c 实现了 main.c 所需的许多功能。是否可以使用链接器通过 file1.c 中的不同实现(具有相同名称)替换单个函数或某些函数?链接器应首先使用 file1.c 中的函数定义,然后将 file2.c 用于剩余的未解析函数。
我希望我的问题是可以理解的;)
谢谢!
【问题讨论】:
-
你能编辑file2吗?在这种情况下,我会选择以更明确的方式使用的功能。例如。借助预处理器开关封装在条件部分中。
-
与您的问题和疑问无关,但以下划线开头并后跟大写字母的符号(例如
_HEADER_H)在所有范围内保留 “实现”(编译器和标准库)。 -
是的,我可以编辑file2。预处理器开关当然是解决这个问题的方法,但我想知道是否有更优雅的方法,也许是通过巧妙地使用链接器(我特别尝试了解参数的顺序在链接过程中如何发挥作用)。
-
@Some程序员老兄:感谢您的澄清,不知道这一点! ;)
-
您可以将一个函数标记为weak symbol。