我想在main
函数之前做一些事情。我有多个源文件。在每个文件中,有一些工作需要在main
之前完成。这在C ++中没有问题,但在C中存在问题。
在C ++中,这可以通过两种方式完成:
例如,static const int __register_dummy_ = __AddRegisterMetaInfo(...);
然而,在C中,任何一种方式都是不可能的。显然,没有构造函数。所以,第一种选择本质上是不可能的。
我认为第二个选项是可能的,但不是用C编译的(我只用Visual C ++测试过。它给出了C2099。)。 C只允许常量为非自动变量。
有没有办法在main之前调用某些函数?
编辑:似乎很多人误解了我真正想做的事情。很抱歉以简单的方式撰写此问题。
我需要做的是实现一种C ++运行时类信息功能,就像MFC's approach一样。在这种方法中,我需要从所有源代码中获取一些信息。例如,假设每个源文件都有一个类的定义,我想查看所有信息(例如,类名和父类)。最简单的方法是在每个文件中放置一个静态构造函数,每个构造函数访问一个全局数据结构并注册其信息。但是,我也希望找到一种在C语言中实现类似内容的方法。因此,只需在pre_main_job
中调用main
就不能成为我的答案。
请注意,这种滥用静态构造函数的方法也可以在LLVM编译器套件中找到。每个优化/分析功能都作为通过实现。所有这些传递都是通过静态构造函数注册的。
答案 0 :(得分:11)
对于许多特定于编译器的解决方案,您可以查看OpenSSL发行版中的fips_premain.c文件(您可以在一堆地方在线查看,例如here)。
MSVC特定部分类似于(FINGERPRINT_premain
是main
之前要执行的函数):
# ifdef _WINDLL
__declspec(dllexport) /* this is essentially cosmetics... */
# endif
void FINGERPRINT_premain(void);
static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; }
# ifdef _WIN64
# pragma section(".CRT$XCU",read)
__declspec(allocate(".CRT$XCU"))
# else
# pragma data_seg(".CRT$XCU")
# endif
static int (*p)(void) = premain_wrapper;
/* This results in pointer to premain to appear in .CRT segment,
* which is traversed by Visual C run-time initialization code.
* This applies to both Win32 and [all flavors of] Win64. */
# pragma data_seg()
答案 1 :(得分:5)
您可以使用特定于编译器的扩展来实现此目的,例如。 gcc允许您使用constructor
function attribute(和匹配的destructor
属性)来使代码在main
之前和main
之后(或exit
)< / p>
答案 2 :(得分:4)
假设你没有将C ++与C ...混合(因为那时你可以在你的c ++类上做静态构造函数,这可能就是你所要求的!)
Crt0
是传统上在main()之前调用的特定于平台的运行时设置。你可以覆盖它,但那很深。
某些嵌入式平台提供_pre_main()
和_post_main()
类型的过程。但我认为这是非标准的。
真的,您的主要切入点是main()
!
如果你控制了Makefile,你可以强迫main成为别的东西,比如
gcc app.c -Dmain=not_really_main
然后将您的真实main()
链接到not_really_main()
。
编辑:还有一种方法:gcc链接器有一个名为ENTRY的变量,它是第一个执行的东西,通常是crt0。再一次,这是非常重量级的,你会非常了解该平台以实现它,但它是另一个你可以“颠覆主要”的地方。
答案 3 :(得分:3)
(我知道,这不是对原始问题的直接回答;但是,对于那些正在寻找在main
的内容之前执行代码的方法的人来说,这是一个答案
我听说过一个更好的主意 - 一个,甚至可移植,可预测行为。在main
函数开头的“main
之前”执行您想要执行的操作(或调用在main
开头执行所需操作的函数)。
如果您控制代码,那么(真的!)不需要像您提议(或引入)那样脆弱且常常无法维护的黑客。