正向插件系统指的是在设计之初就已经定义好了一族用于特定功能的接口,然后通过共享库的形式隔离不同的实现策略,这样做不仅可以做到运行时按需选择实现策略,而且非常有利于功能的模块化测试。这种模式的插件系统是非常常见的,比如Adobe PS 对于不同文件格式、不同滤镜等的支持就是采用的就是正向插件系统设计。
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <assert.h> typedef int (*calc_t)(int a, int b); int main() { void* module = dlopen("./libadd.dylib", RTLD_NOW); assert(module != NULL); calc_t calc = (calc_t) dlsym(module, "calc"); assert(calc != NULL); do { int i_first; printf("input the first number:"); scanf("%d", &i_first); int i_second; printf("input the second number:"); scanf("%d", &i_second); int i_result = (*calc)(i_first, i_second); printf("the result is %d\n\n", i_result); } while (true); dlclose(module); return 0; }
extern "C" int calc(int a, int b) { return a + b; }
extern "C" int calc(int a, int b) { return a - b; }
extern "C" int calc(int a, int b) { return a * b; }
extern "C" int calc(int a, int b) { return a / b; }
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <assert.h> typedef int (*calc_t)(int a, int b); struct dl_mod { void* module; calc_t calc; } mod[4]; int main(int argc, char* argv[]) { for (int i = 0; i < 4; i++) { void* module = dlopen(argv[i + 1], RTLD_NOW); assert(module != NULL); calc_t calc = (calc_t) dlsym(module, "calc"); assert(calc != NULL); mod[i].module = module; mod[i].calc = calc; } do { int i_calc; printf("select the calculate number:"); scanf("%d", &i_calc); int i_first; printf("input the first number:"); scanf("%d", &i_first); int i_second; printf("input the second number:"); scanf("%d", &i_second); int i_result = (*(mod[i_calc].calc))(i_first, i_second); printf("the result is %d\n\n", i_result); } while (true); for (int i = 0; i < 4; i++) { dlclose(mod[i].module); } return 0; }
extern "C" char* description() { return "add"; }
extern "C" char* description() { return "minus"; }
extern "C" char* description() { return "multiply"; }
extern "C" char* description() { return "divide"; }
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <assert.h> typedef char* (*description_t)(); typedef int (*calc_t)(int a, int b); struct dl_mod { void* module; char* desc; calc_t calc; } mod[4]; int main(int argc, char* argv[]) { for (int i = 0; i < 4; i++) { void* module = dlopen(argv[i + 1], RTLD_NOW); assert(module != NULL); description_t desc = (description_t) dlsym(module, "description"); assert(desc != NULL); calc_t calc = (calc_t) dlsym(module, "calc"); assert(calc != NULL); mod[i].module = module; mod[i].desc = (*desc)(); mod[i].calc = calc; } do { for (int i = 0; i < 4; i++) { printf("%d:%s\n", i, mod[i].desc); } int i_calc; printf("select the calculate number:"); scanf("%d", &i_calc); int i_first; printf("input the first number:"); scanf("%d", &i_first); int i_second; printf("input the second number:"); scanf("%d", &i_second); int i_result = (*(mod[i_calc].calc))(i_first, i_second); printf("the result is %d\n\n", i_result); } while (true); for (int i = 0; i < 4; i++) { dlclose(mod[i].module); } return 0; }
./calc libadd.dylib libminus.dylib libmultiply.dylib libdivide.dylib 0:add 1:minus 2:multiply 3:divide select the calculate number:0 input the first number:3 input the second number:4 the result is 7 0:add 1:minus 2:multiply 3:divide select the calculate number: