我们对入口函数之前可以做什么

来源:互联网 发布:乐视tv电视直播软件 编辑:程序博客网 时间:2024/04/29 14:01
从来没有过这样的需求, 不过这个一定很有趣, 我在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
0 0
原创粉丝点击