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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| /** * 参考busybox框架代码实现程序分身。 * 应用场合:很多业务处理可能需要不同的程序,但又有很多共同部分(如初始化)。 * 则可以使用同一套代码,但创建多个链接的方式实现, * 综合考虑了代码组织维护和程序运行两方面。 * 具体示例:cgi业务程序 * 测试说明: * gcc busybox_main.cpp * cp a.out foo * cp a.out hello * 分别执行foo和hello和a.out(执行a.out没有输出信息) */ #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <unistd.h> #include <string.h>
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // 以下为不同业务处理模块程序,每个函数可以是独立的,也可以是有部分共用的初始化 // 但不能共享数据,因为对外,它们是单独的程序 int foo(int argc, char *argv[]) { printf("foo\n"); return 0; }
int bar(int argc, char *argv[]) { printf("bar\n"); return 0; }
int hello(int argc, char *argv[]) { printf("hello\n"); for (int i = 0; i < argc; i++) { printf("argv[%d]: %s\n", i, argv[i]); } return 0; } // >>>>>>>>>>>>>>>>>>>>>>>>>>>> 业务模块函数 结束
#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
struct bb_applet { const char *name; // 程序名称 int (* applet_main)(int argc, char* argv[]); // 仿main函数 };
// 全局结构体数组,保存程序名称与对应的执行函数 static struct bb_applet g_applets[] = { {"foo", foo}, {"bar", bar}, {"hello", hello} };
static int cmp_name(const void *a, const void *b) { const struct bb_applet *aa = (struct bb_applet *)a; const struct bb_applet *bb = (struct bb_applet *)b; return strcmp(aa->name, bb->name); }
static int applet_name_compare(const void *name, const void *idx) { int i = (int)(ptrdiff_t)idx - 1; return strcmp((const char*)name, g_applets[i].name); }
int find_applet_by_name(int size, const char *name) { // 当数量达到一定时,使用二分查找,这样快速,否则直接比较即可 if (size > 8) { void *p; p = bsearch(name, (void*)(ptrdiff_t)1, size, 1, applet_name_compare);
return (int)(ptrdiff_t)p - 1; } else { for (int i = 0; i < size; i++) { if (strcmp(name, g_applets[i].name) == 0) return i; } return -1; } }
int main(int argc, char *argv[]) { char* p = NULL; char* applet_name = argv[0]; int size = ARRAY_SIZE(g_applets); int applet_no = -1;
if ((p = strrchr (applet_name, '/')) != NULL) { applet_name = p + 1; }
// 测试代码 for (int i = 0; i < size; i++) { //printf("org name[%d]: %s\n", i, g_applets[i].name); } // 先进行快排 qsort(g_applets, size, sizeof(g_applets[0]), cmp_name);
// 测试代码 for (int i = 0; i < size; i++) { //printf("name[%d]: %s\n", i, g_applets[i].name); }
// 再使用二分查找 applet_no = find_applet_by_name(size, applet_name);
// 如果找到,则执行 if (applet_no != -1) g_applets[applet_no].applet_main(argc, argv);
return 0; }
|