【问题标题】:Importing function under a different name以不同的名称导入函数
【发布时间】:2019-01-24 16:54:16
【问题描述】:

这是否可以在 C 中以不同的名称导入库函数?

就像理想地说这种假的 C 语法:

 char *malloc(int) as mymalloc;

而不是库文件中已知的malloc,它变为mymalloc。并且标识符 malloc 未声明,可用于将来的声明。

当第三方大头文件可以在以后可选地包含时,我需要它用于某些特定用例,但必须始终使用一些函数。因此,我需要另一个微标头,它定义了与较大标头稍后声明(或不声明)相同的几个函数。这一切都是编译为 C 的编程语言的一部分,所以奇怪的要求是小头文件必须在大头文件之前定义函数。我也不能使用一些琐碎的ifdef 解决方案,因为大标题不了解我,我无法修改它。有问题的函数将复杂的结构指针作为参数,但我只是将它们声明为谈话void*,因此编译器将在“不兼容的重新定义”处咆哮。

CLUMSY_STRUCTURE *create_struct();
do_something(CLUMSY_STRUCTURE *);

CLUMSY_STRUCTUREs 的定义很长,我不希望它们出现在我的小标题中。

我也不确定即使我重新定义 CLUMSY_STRUCTURE 编译器在看到第二个声明时是否会认为两个声明是兼容的。

【问题讨论】:

  • 您能编写自己的所需名称的函数来简单地调用另一个函数吗?
  • 如果你将“大头文件”中声明的子集保存为“小头文件”,那么“小头文件”可以安全地包含在“大头文件”之前。所以我不确定我是否理解这个问题。你能创建一个minimal, complete and verifiable example 来说明你的问题吗?
  • 不,你不能...
  • #include "LargeHeader" 之类的有什么问题?

标签: c


【解决方案1】:

是的,你可以!

您只需要构建一个包含适当标头并调用标准库函数的小型包装器,然后从您想要的位置调用该包装器。唯一的限制是名称 malloc 不能接收外部链接,因为 if 会在链接时与标准库标识符冲突。

这是一个代码示例:

mymalloc.h

void * mymalloc(int size);
void myfree(void * pt);

mymalloc.c

#include <stdlib.h>
#include "mymalloc.h"

void *mymalloc(int size) {
    return malloc(size);
}

void myfree(void *pt) {
    free(pt);
}

main.c

#include <stdio.h>
#include <string.h>
#include "mymalloc.h"

int main() {
        char *malloc = mymalloc(64);
        strcpy(malloc, "foo bar");
        printf("%s\n", malloc);
        myfree(malloc);
        return 0;
}

main 中的 malloc 指针没有链接,因此它可以在没有警告的情况下工作。如果它是一个全局变量,它应该被声明为静态来接收内部链接

但请注意:按标准允许以这种方式重用标准库中的名称并被编译器接受,但它会使未来的读者感到困惑,应尽可能避免。由于明确的要求,我只在这里做了。永远不要在正常代码中这样做,至少不要假装我建议过它!

【讨论】:

  • 必须提及LD_PRELOAD trick
  • @SanderDeDycker:OP 没有标记 Linux 并且 LD_PRELOAD 不可移植。如果我们这样做,我们应该说 gcc 弱符号,它会明确地允许覆盖库符号。
  • @SanderDeDycker:没问题,这就是我在自己的评论中提到 gcc 弱符号的原因。但我不确定它是否真的需要在答案中。无论如何感谢 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 2018-02-26
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多