在C之前调用main之前的一些函数

时间:2011-02-02 23:02:04

标签: c static-variables

我想在main函数之前做一些事情。我有多个源文件。在每个文件中,有一些工作需要在main之前完成。这在C ++中没有问题,但在C中存在问题。

在C ++中,这可以通过两种方式完成:

  1. 利用全局类/结构的构造函数。
  2. 将函数调用为全局变量
  3. 例如,static const int __register_dummy_ = __AddRegisterMetaInfo(...);

    然而,在C中,任何一种方式都是不可能的。显然,没有构造函数。所以,第一种选择本质上是不可能的。

    我认为第二个选项是可能的,但不是用C编译的(我只用Visual C ++测试过。它给出了C2099。)。 C只允许常量为非自动变量。

    有没有办法在main之前调用某些函数?


    编辑:似乎很多人误解了我真正想做的事情。很抱歉以简单的方式撰写此问题。

    我需要做的是实现一种C ++运行时类信息功能,就像MFC's approach一样。在这种方法中,我需要从所有源代码中获取一些信息。例如,假设每个源文件都有一个类的定义,我想查看所有信息(例如,类名和父类)。最简单的方法是在每个文件中放置一个静态构造函数,每个构造函数访问一个全局数据结构并注册其信息。但是,我也希望找到一种在C语言中实现类似内容的方法。因此,只需在pre_main_job中调用main就不能成为我的答案。

    请注意,这种滥用静态构造函数的方法也可以在LLVM编译器套件中找到。每个优化/分析功能都作为通过实现。所有这些传递都是通过静态构造函数注册的。

4 个答案:

答案 0 :(得分:11)

对于许多特定于编译器的解决方案,您可以查看OpenSSL发行版中的fips_premain.c文件(您可以在一堆地方在线查看,例如here)。

MSVC特定部分类似于(FINGERPRINT_premainmain之前要执行的函数):

# 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开头执行所需操作的函数)。

如果您控制代码,那么(真的!)不需要像您提议(或引入)那样脆弱且常常无法维护的黑客。