解决在静态库“未定义的参考”一个重定向
海兰,我有以下结构:即F2采用F1解决在静态库“未定义的参考”一个重定向
lib1.a
U f1
00000000 T f2
lib2.a
00000000 T f3
main.c:
#define f1(a, b) f3(a, b)
int main(){
f2(a, b);
}
注意。
有没有一种方法可以编译这个解决'未定义的引用'而无需修改代码或库?
主要问题不是为什么我得到'未定义的引用'为f1(因为它是未定义的,显而易见),但我如何编译这个没有执行f1。一些类似于映射的东西,我想在编译完成类似于重定向之后被称为f3而不是f1(这就是为什么在main.c中定义集合)。
感谢
====编辑==: 好了,所以,由于这样的事实,这个问题太难理解,我会添加来源:
lib2.c - - > $ gcc -c lib2.c; AR RCS lib2.a lib2.o
#include <stdio.h>
#include <stdlib.h>
int f3(int c, char *d)
{
printf("Rly: %d %s \n", c,d);
return 1;
}
lib2.h
int f3(int c, char *d);
lib.c - > $ GCC -c lib.c; AR RCS lib.a lib.o
#include <stdio.h>
#include <stdlib.h>
int f2(int c, char *d)
{
printf("%d %s\n", c,d);
f1(c,d);
return 1;
}
lib.h
int f2(int c, char *d);
的main.c - > $ GCC的main.c lib.a lib2.a
#include <stdio.h>
#include <stdlib.h>
#include "lib.h"
#include "lib2.h"
#define f1(a, b) f3(a, b)
int main(int argc, char **argv)
{
f2(argc, argv[0]);
return
}
这是我为创建类似场景而创建的文件。 无法修改lib.a和lib2.a。只有main.c和我如何编译它们。
你不能用宏来完成这种“重定向”(#define
)。
要理解为什么不呢,记得宏扩展只是简单的文本替换它由预处理器(cpp
)来完成 - 运行前的文件交给编译器(cc1
),它实际产生的汇编代码第一遍。特别是,当您在main.c
中定义一个宏时,它只会在main.c
的预处理过程中看到,因此它必须发生的任何影响必须发生在那里。宏有时可以用来代替函数,但它们是完全不同的动物。
因此,在您的程序中,如果在main.c
的任何位置使用标识符f1
,则预处理器会将其替换为f3
。但事实并非如此,所以这个宏并没有任何效果,并且cc1
从来不知道它甚至不存在,连接器ld
也不知道。如果你可以在lib.c
中定义宏,它会做你想做的事,但你说你不能那样做。
实现你想要的最简单和最便携的方法是在main.c
(或任何其他源文件,也许是一个新文件)中实际定义f1
作为全局函数。
int f1(int c, char *d)
{
return f3(c, d);
}
它也可以告诉的是,在目标代码f1
任何引用应被解析为f3
链接器来实现的,但它是不可移植。如果您的系统使用GNU ld
连接,然后
gcc -Wl,--defsym=f1=f3 main.c lib.a lib2.a
会做到这一点。但是我建议,只有作为最后的手段,如果由于某种原因,简单的方法是完全不合适的。
注意,这只会工作,如果你的f1
有完全相同的原型(参数,的参数类型,返回类型)作为呼叫f1
在lib.c
期待。目前您的lib.c
应该产生一个警告(随时注意警告!!!!!),因为你叫f1
没有范围的声明。在现实中lib.c
应该有一个像int f1(int, char*);
声明呼叫之前的某个地方出现。 (如果你离开它,你就会得到一个“隐式声明”,但你不能信任它永远是正确的。)
谢谢,很好的解释了:)“--defsym”似乎什么,我一直在寻找最佳的解决方案。 – dFroze
的【什么是未定义参考/解析的外部符号错误可能的复制以及如何修复它?(https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Olaf
这不是一个编译器错误。 – Olaf
@Olaf谢谢你的回答。我会尽力记住那篇文章。但这里的问题不是为什么我有“未定义的参考”,但如果有一种方法与LIB1和LIB2编译它,因为它是只与main.c中的变化,如果需要的。请注意,main.c必须调用f2,我希望f2调用f3而不是f1。 – dFroze