我有一个a.h和a.c,它提供了函数的接口和实现
//a.h
#ifndef A_H
#define A_H
int op();
#endif
//a.c
#include "a.h"
int op(){
return 1;
}
类似地,我有b.h和b.c,它给出了一个具有相同名称但具有不同实现的函数的接口
//b.h
#ifndef B_H
#define B_H
int op();
#endif
//b.c
#include "b.h"
int op(){
return 2;
}
现在,我想将它们与主程序链接
#include <stdio.h>
int op();
int main(){
printf( "returned = %d\n ", op());
}
为此,我首先将a.c和b.c分别编译为a.o和b.o。
gcc -c a.c; gcc -c b.c
然后我想把它们连在一起。这里的一个通常目标是让main.c选择&#39; op&#39;使用链接命令中首先出现的实现。所以,理想情况下:
gcc a.o b.o main.c
应该给我一个执行时返回1的可执行文件,gcc b.o a.o main.c
应该给我一个执行时返回2的可执行文件。但我收到错误消息
ld: 1 duplicate symbol for architecture x86_64
其实我并不感到惊讶。我的问题是:如何让main.c使用第一个实现的实现?感谢。
答案 0 :(得分:3)
根据链接器参数顺序选择使用哪个函数通常是一个坏主意。但是,您的要求可以使用weak symbols实现。
要使函数“弱”,即由另一个实现覆盖,请使用GCC __attribute__((weak))
标记它,例如:
int op(void) __attribute__((weak));
int op(void){
return 2;
}
如果以这种方式将两个实现声明为“弱”,那么首先出现的实现将是首选。
如果您只将一个标记为弱,则无论链接顺序如何,都将严格优先选择另一个。我建议采用这种方式来提高代码的可维护性。
答案 1 :(得分:3)
一个选项:
制作两个静态库 - 一个来自a.o
,另一个来自b.o
。
ar libA.a a.o
ar libB.a b.o
在链接行中,使用您希望在另一个库之前获得更高优先级的库。
gcc main.c -L. -lA -lB