1. 程式人生 > >C語言 設定在main 之前執行的函式

C語言 設定在main 之前執行的函式

我們知道 C++的物件全域性物件的建構函式會在main之前執行,例如windows MFC裡面,在WinMain 函式前聲明瞭一個theApp物件,其建構函式就在WinMain之前執行,其實在C語言中很早就有了,在gcc中可以使用__attribute__關鍵字指定如下(注意,這個和諸如on exit之類可不一樣,這個是編譯器編譯的時候就決定了的)

#include <stdio.h>
void before() __attribute__((constructor));
void after() __attribute__((destructor));

void before()
{
	printf("this is function %s/n", __func__);
	return;
}

void after()
{
	printf("this is function %s/n", __func__);
	return;
}

int main(int argc, char **argv)
{
	printf("this is function %s/n", __func__);
	return 0;
}
指定了函式在main之前或之後執行。
當然也可以指派多個,而且在申明時 
void before() __attribute__((constructor));
void __attribute__((constructor)) before();
__attribute__((constructor)) void before();

這3種都是對的,__attribute__(())寫法比較隨意,當一般推薦放在後面,當然定義函式體的時候 __attribute__(()) 不能放在後面,推薦定義函式的時候一般不要使用,這就是為什麼推薦第一種的原因,__attribute__屬性列表的用法還有還多,記憶體對齊,函式格式, 等等等等就不一一列舉了。man gcc 查詢下 __attribute__可以發現這些,另標準庫和Linux核心裡面也有不少。

也可以一次指定多個屬性 如下:

void func(void) __attribute__((constructor destructor));

attribute 是gcc、 g++的關鍵字,VC是不能用這個的,

如果您是在Windows下你可以指定設定資料段來做,以實現同樣功能,如下:

#include <stdio.h>
 
int main(int argc, char ** argv)
{
	printf("%s\n", "main");
	return 0;
}
 
int before()
{
	printf("%s\n", "before");
	return 0;
}
 
int after()
{
	printf("%s\n", "after");
	return 0;
}

typedef int func();

#pragma data_seg(".CRT$XIU")
static func *before_function_array[] = { before };

#pragma data_seg(".CRT$XPU")
static func *after_function_array[] = { after };
#pragma data_seg()

attribute還有個應用:

增加函式別名,下面,當然下面那個就不能是main了,要不就重複定義了

# include <stdio.h>
int main(int argc, char **argv) __attribute__((alias("LinuxMain")));

int LinuxMain(int argc, char **argv)
{
    printf("%s\n", __func__);
    return 0;
}

int main1(int argc, char **argv)
{
    printf("%s\n", __func__);
    return 0;
}