在main之前初始化自定义输出流

时间:2017-02-14 20:33:13

标签: c stdout extern

假设我想编写一个提供自定义输出流的API(用于C / Linux),例如stdout,但应该将其称为not_stdout。所以我可以要求使用我的API的人总是通过调用初始化init_the_stream()的函数extern FILE* not_stdout来开始他们的主程序。

但我真正喜欢的是我的流在main()之前被初始化,因此它就像stdout一样。

我猜这有点难以以可移植的方式进行,因为C标准希望先前的主要初始化变量是常量或字符串文字,并且stdout得到特殊的编译器处理。但我不确定,所以我想问:

是否可以编写C库,以便在包含库时extern FILE* not_stdout的第一行之前初始化main()之类的内容?

1 个答案:

答案 0 :(得分:1)

在gcc和clang上,您可以使用__attribute__((constructor))(非标准C)。

示例:

#include <stdio.h>
__attribute__((constructor))
static void not_stdout__init(void)
{
   puts("initializing not_stdout");
}
int main()
{
    puts("main");
}

它适用于动态链接(.so)或加载(dlopen)ELF库 - 如果库提供了这样的钩子,它们将在链接到库时被调用。

如果您想要可移植,可以让初始化程序在外部可见(无static),并且只有在支持的情况下才有条件地添加构造函数属性。这样,如果没有机制可以让他们的平台为他们做这件事,那么你的用户可以从main手动调用初始化程序。