假设我想编写一个提供自定义输出流的API(用于C / Linux),例如stdout
,但应该将其称为not_stdout
。所以我可以要求使用我的API的人总是通过调用初始化init_the_stream()
的函数extern FILE* not_stdout
来开始他们的主程序。
但我真正喜欢的是我的流在main()
之前被初始化,因此它就像stdout
一样。
我猜这有点难以以可移植的方式进行,因为C标准希望先前的主要初始化变量是常量或字符串文字,并且stdout
得到特殊的编译器处理。但我不确定,所以我想问:
是否可以编写C库,以便在包含库时extern FILE* not_stdout
的第一行之前初始化main()
之类的内容?
答案 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手动调用初始化程序。