2017-09-21 41 views
-1

海兰,我有以下结构:即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和我如何编译它们。

+1

的【什么是未定义参考/解析的外部符号错误可能的复制以及如何修复它?(https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Olaf

+0

这不是一个编译器错误。 – Olaf

+0

@Olaf谢谢你的回答。我会尽力记住那篇文章。但这里的问题不是为什么我有“未定义的参考”,但如果有一种方法与LIB1和LIB2编译它,因为它是只与main.c中的变化,如果需要的。请注意,main.c必须调用f2,我希望f2调用f3而不是f1。 – dFroze

回答

0

你不能用宏来完成这种“重定向”(#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有完全相同的原型(参数,的参数类型,返回类型)作为呼叫f1lib.c期待。目前您的lib.c应该产生一个警告(随时注意警告!!!!!),因为你叫f1没有范围的声明。在现实中lib.c应该有一个像int f1(int, char*);声明呼叫之前的某个地方出现。 (如果你离开它,你就会得到一个“隐式声明”,但你不能信任它永远是正确的。)

+0

谢谢,很好的解释了:)“--defsym”似乎什么,我一直在寻找最佳的解决方案。 – dFroze