gcc为函数提供了几种类型的属性,其中包含:构造函数(constructors)和析构函数(destructors)。
程序员应当使用类似下面的方式来指定这些属性:
带有"构造函数"属性的函数将在main()函数之前被执行,而声明为"析构函数"属性的函数则将在main()退出时执行。
下面给出一个简单的程序作为例子:
/* test.c */
#include<stdio.h>
__attribute__((constructor)) void before_main()
{
printf("before main/n");
}
__attribute__((destructor)) void after_main()
{
printf("after main/n");
}
int main()
{
printf("in main/n");
return 0;
}
[root@localhost tmp]# gcc -o test test.c
[root@localhost tmp]# ./test
before main function
init main function
after main function
before main function
init main function
after main function
为了便于单元测试,做了一个utl_cmd的小模块,它会负责插入命令,解析命令并执行。
利用这些命令,可以方便的在程序运行过程中对模块进行测试。
利用这些命令,可以方便的在程序运行过程中对模块进行测试。
而这里有个比较麻烦的问题是,必须要调用utl_cmd_insert先把测试命令插入到命令序列中。
否则utl_cmd模块,也不知道都有哪些命令可以支持。
利用构造函数(constructors)这个特性,就不需要再在main函数中先调用插入命令的函数了。
- int mplayer_test_init() __attribute__((constructor)) ;
- int mplayer_test_init()
- {
- char *helper =
- "\tmplayer prepare [WINDOW COUNT]\n"
- "\tmplayer play [chn] [fname]\n"
- "\tmplayer stop [chn]\n"
- "\tmplayer over\n"
- "\tmplayer step [chn]\n"
- "\tmplayer back [chn]\n"
- "\tmplayer fast [chn] [speed 2,4,8,16,32]\n"
- "\tmplayer slow [chn] [speed 2,4,8,16,32]\n"
- "\tmplayer pause [chn]\n"
- "\tmplayer resume [chn]\n"
- "\tmplayer allplay\n"
- "\tmplayer allspeed [fast | slow] [speed]\n"
- "\tmplayer allstop\n"
- ;
- utl_cmd_insert("mplayer", "mplayer test", helper, mplayer_main);
- return 0;
- }
还有个需要注意之处:
如果,测试代码在一个单独的模块,单独的文件中,而这个文件中的任何函数都没被外部调用的话,
可能会导致自动运行不成功。
原因是,链接过程中,将这个文件整个的删除掉了。
为了避免此问题的发生,可以在链接时,加入-Wl,--whole-archive -l(你的库) -Wl,--no-whole-archive 来避免此问题
如果,测试代码在一个单独的模块,单独的文件中,而这个文件中的任何函数都没被外部调用的话,
可能会导致自动运行不成功。
原因是,链接过程中,将这个文件整个的删除掉了。
为了避免此问题的发生,可以在链接时,加入-Wl,--whole-archive -l(你的库) -Wl,--no-whole-archive 来避免此问题