解决未定义的引用'在具有重定向的静态库中

时间:2017-09-21 15:40:06

标签: c undefined-reference

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以及我如何编译它们。

1 个答案:

答案 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*);的声明出现在呼叫之前的某个地方。 (如果你把它留下来,你得到一个“隐含声明”,但你不能相信它总是正确的。)