从来没有过这样的需求, 不过这个一定很有趣, 我在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
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