函数在main调用之前被调用

从来没有过这样的需求, 不过这个一定很有趣, 我在stackoverflow看到这个标题时, 第一时间马上想到了C++中利用全局对象的函数就可以达到这个目的. 正如stackoverflow下面的回帖:

class StartUp
{
public:
   StartUp()
   { foo(); }
};

StartUp startup; // A global instance

C++中的构造甚至可以直接写成下面这样, foo也会被调用在main之前

int b = foo();
int main()
{
}

显然, C中是没有class概念的, 所以就不太好弄了, 不过不必担心, GCC提供了方便, 直接上代码:

#include <stdio.h>

void beforeMain (void) __attribute__ ((constructor));

void
beforeMain (void)
{
  printf ("\nbefore main\n");
}

int
main (int argc, char **argv)
{
  printf ("\ninside main \n");
  return 0;
}

 这样, 同样会在main调用之前, 调用这个指定的函数beforeMain, 不尽如此, GCC还提供了一个destructor操作, 将指定函数调用发生在main调用完成之后. GCC确实很好玩, 但是如果是用VC编译器呢? 不幸的是VC编译器不支持这样玩. stackoverflow上高人很多, 我一下子就搜索到了方法(其实我也想到了利用CRT的初始化来达到这个目的, 但我不知道如何写代码) 

#include <stdio.h>

static
void __cdecl after(void)
{
	printf("after!\n");
}

static
void __cdecl before(void)
{
	printf("before\n");
	atexit(after);
}

#pragma section(".CRT$XCU",read)
__declspec(allocate(".CRT$XCU")) static void (__cdecl* fbefore)(void) = before;

int main()
{
	printf("Main\n");
	return 0;
}

这段代码干嘛了呢, 实际上就是在.CRT$XCU里分配了一个函数地址, 并使其指向before, 当程序一启动时, 程序首先是运行crt的初始化代码, 比如初始化全局对象呀什么的, 这些初始化函数都以一个表的形式包含在.CRT$XCU这个节里面, crt初始化时会循环调用这些函数来进行初始化. 

atexit 是指定某个函数在退出时插入到crt反初始化表的功能.

stackoverflow上的参考:
http://stackoverflow.com/questions/10897552/call-a-function-before-main
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
msdn参考:
http://msdn.microsoft.com/en-us/library/bb918180.aspx
http://blogs.msdn.com/b/vcblog/archive/2006/10/20/crt-initialization.aspx

你可能感兴趣的:(crt)