Hy,我有以下结构:
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);
}
请注意,f2使用f1。
有没有办法编译这将解决未定义的引用'没有修改代码或库?
主要问题不是我为什么会得到未定义的引用'对于f1(因为它未定义,显而易见),但是如何在不实现f1的情况下编译它。类似于映射的东西,我想在编译完成类似于重定向之后被称为f3而不是f1(这就是为什么在main.c中设置了define)。
由于
====已编辑==: 好的,所以,由于问题太难理解,我将添加来源:
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 - &gt; $ 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 - &gt; $ 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以及我如何编译它们。
答案 0 :(得分:0)
您无法使用宏(#define
)完成此类“重定向”。
要理解为什么不这样做,请记住,宏扩展只是简单的文本替换,由预处理器(cpp
)完成 - 在文件传递给编译器之前运行的第一个传递(cc1
)实际上创建汇编代码。特别是,当您在main.c
中定义一个宏时,它只会在main.c
的预处理过程中看到,所以它必须在那里产生任何影响。有时可以使用宏而不是函数,但它们实际上是完全不同的动物。
因此,在您的程序中,如果f1
中的任何位置使用了标识符main.c
,则预处理程序会将其替换为f3
。但它不是,所以宏没有任何影响,cc1
永远不会知道它甚至存在,链接器ld
也没有。如果你可以在lib.c
中定义宏,它会做你想要的,但是你说你做不到。
实现您想要的最简单,最便携的方法是将f1
实际定义为main.c
(或任何其他源文件,可能是新文件)中的全局函数。
int f1(int c, char *d)
{
return f3(c, d);
}
也可以通过告诉链接器将对象代码中对f1
的任何引用解析为f3
来实现,但它是不可移植的。如果您的系统使用GNU ld
链接器,那么</ p>
gcc -Wl,--defsym=f1=f3 main.c lib.a lib2.a
会这样做。但我建议,只有作为最后的手段,如果出于某种原因,简单的方法是完全不合适的。
请注意,只有当f1
具有完全相同的原型(参数,参数类型,返回类型)与f1
中对lib.c
的调用所期望的相同时,这才会起作用。目前你的lib.c
应该发出警告(总是注意警告!!!!!),因为你在没有范围声明的情况下调用f1
。实际上lib.c
应该有一个类似int f1(int, char*);
的声明出现在呼叫之前的某个地方。 (如果你把它留下来,你得到一个“隐含声明”,但你不能相信它总是正确的。)