使用重定向解决静态库中的 'undefined reference'

Solving 'undefined reference' in a static lib with a redirect

嘿,我有以下结构:

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。

有没有一种编译方法可以在不修改代码或库的情况下解决 'undefined reference'?

主要问题不是为什么我得到 f1 的 'undefined reference'(因为它未定义,很明显),而是我如何在不实现 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) 完成这种 "redirect"。

要理解为什么不,请记住宏扩展只是简单的文本替换,由预处理器完成 (cpp) - 在文件交给编译器之前运行的第一遍 (cc1) 实际上创建汇编代码。特别是,当您在 main.c 中定义一个宏时,它仅在 main.c 的预处理期间可见,因此它将产生的任何效果都必须在那里发生。有时可以用宏代替函数,但它们真的是完全不同的动物。

因此在您的程序中,如果标识符 f1main.c 中的任何位置使用,预处理器会将其替换为 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 中对 f1 的调用完全相同的原型(参数、参数类型、return 类型)时,这才会起作用=22=] 期待。目前你的 lib.c 应该产生一个警告(总是注意警告!!!!!)因为你调用 f1 没有在范围内声明。实际上 lib.c 应该有一个像 int f1(int, char*); 这样的声明出现在调用之前的某处。 (如果你把它漏掉,你会得到一个 "implicit declaration" 但你不能相信它总是正确的。)