背景
最近在看某开源项目源码,发现代码里对main函数的参数做了处理,根据传入的程序名称(即argv[0]),调用不同的函数。笔者认为这个小技巧挺不错的,本文就整理实践一下。
完整源码
main.c源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| /** 作用: 只有可执行程序文件名是foo或bar时才能正常执行,其它任何字符串都不行。
作用: 如有服务端、客户端的小程序,可在一个文件中实现,编译,然后改名,根据可执行文件不同,调用不同函数,达到“多程序”目的。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
int foo_1(int argc, char* argv[]) { printf("hello foo.\n"); }
int bar_1(int argc, char* argv[]) { printf("hello bar.\n"); }
#define CMD_FOO "foo" #define CMD_BAR "bar"
int main(int argc, char *argv[]) { char* p; char* cmdname = *argv;
if ((p = strrchr (cmdname, '/')) != NULL) { cmdname = p + 1; }
if (strcmp(cmdname, CMD_FOO) == 0) {
if (foo_1 (argc, argv) != 0) return -1;
return 0;
} else if (strcmp(cmdname, CMD_BAR) == 0) {
if (bar_1 (argc, argv) != 0) return -1;
return 0;
}
fprintf (stderr, "Identity crisis - may be called as `" CMD_FOO "' or as `" CMD_BAR "' but not as `%s'\n", cmdname); return -1; }
|
编译
执行:
1 2 3 4 5 6 7 8
| $ ./a.out Identity crisis - may be called as `foo' or as `bar' but not as `a.out' $ cp a.out foo $ cp a.out bar $ ./foo hello foo. $ ./bar hello bar.
|
实践应用、小结
在socket测试中,有客户端、服务端代码,可分别在不同文件中实现,但只有一个入口main函数,只用一个Makefile,在Makefile中将生成的可执行文件改名为client、server,然后就得到2个程序了。这样就不需要维护2个Makefile,编译2次了。从效率上看,还是可以试试。
本文所述的,只是小技巧,对于大型项目来说,不能这样做。但其思想,还是值得我们学习的。
李迟 2018.7.25 中午