覆盖C库函数,调用原始函数

hyd*_*yde 14 c gcc

我对这段代码的工作方式和原因感到有些困惑.在我参与过的任何项目中,我都没有遇到过这种情况,我甚至都没想过会自己做.

override_getline.c:

#include <stdio.h>

#define OVERRIDE_GETLINE

#ifdef OVERRIDE_GETLINE
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
    printf("getline &lineptr=%p &n=%p &stream=%p\n", lineptr, n, stream);
    return -1; // note: errno has undefined value
}
#endif
Run Code Online (Sandbox Code Playgroud)

main.c中:

#include <stdio.h>

int main()
{
    char *buf = NULL;
    size_t len = 0;
    printf("Hello World! %zd\n", getline(&buf, &len, stdin));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

最后,示例编译并运行命令:

gcc main.c override_getline.c && ./a.out
Run Code Online (Sandbox Code Playgroud)

使用OVERRIDE_GETLINEdefine,调用自定义函数,如果注释掉,则调用普通库函数,并且两者都按预期工作.

问题

  1. 这个的正确用语是什么?"覆盖","阴影",还有什么?

  2. 这是gcc特定的,或POSIX,还是ANSI C,甚至是未定义的?

  3. 如果函数是ANSI C函数或(如此处)POSIX函数,它会有什么不同吗?

  4. 调用覆盖函数在哪里?通过.o相同链接中的其他文件,至少,我也假设.a文件也添加到链接命令.如何使用-l链接器的命令行选项添加静态或动态库?

  5. 如果可能,如何从覆盖的getline调用getline的库版本?

Som*_*ude 17

在库中搜索之前,链接器将首先在命令行中搜索您提供的符号.这意味着一旦看到getline已定义,它将不再寻找另一个getline符号.这就是连接器在所有平台上的工作方式.

这当然对你的第五点有影响,因为没有可能调用"原始" getline,因为你的函数从链接器的角度来看的原始函数.

对于第五点,您可能想看看例如这个旧答案.