如何让软件支持扩展功能

简介:
作者:gfree.wind@gmail.com
博客:blog.focus-linux.net   linuxfocus.blog.chinaunix.net
 
微博:weibo.com/glinuxer
QQ技术群:4367710
 
本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
=======================================================
作为程序员的我们,必须保证灵活的设计,才能够应付变化的需求。 但是,当把二进制程序发布给用户以后,用户有了新的需求,如果只能由开发者对程序进行修改,无疑是低效率的。而且有的时候,某些用户的需求,应用并不广泛,开发者不可能为一个用户添加该功能。这时候,如果该程序可以支持用户自定义的扩展功能,无疑是对用户是一大福音。

那么,如何让我们的程序支持用户自定义的扩展功能呢?恩~~,还是从Linux的宝库里面寻找吧。今天选择两个学习对象:1. iptables;2. tc

iptables的扩展实现:为了实现新的扩展,需要在iptables的源代码目录下的extensions目录添加新的功能的代码。iptables的扩展功能框架非常清晰,只需要按照iptables的match结构 xtables_match和target结构xtables_target的定义,实现相应的功能即可。具体的参见 http://blog.chinaunix.net/uid-23069658-id-3230608.html 这篇文章。(该文章的iptable版本较低,数据结构与最近版本的iptables完全不一致) 话说,我之前对于iptable的扩展是一窍不通。后来通过该文章知道了如何扩展iptables。几天的时间,就实现了多个iptables的扩展功能——包括用户态和内核态的代码。由此可见, iptables的扩展架构多么友好。但是这里也有个小问题。这样的扩展方式,需要重新编译iptables的代码,生成新的iptable二进制文件。这与我们心目中理想的扩展还差了一小步,稍微有点难以接受。试想,现在的浏览器大都支持扩展插件,有哪个插件需要重新编译浏览器的?

我们C语言程序员也可以实现这样的功能!让我们学习一下tc的扩展吧。以tc中的filer为例。tc的用户(必须也是程序员呵),可以实现自己的filter的实现,并将生成的so库文件放置在tc的库目录下。那么该扩展功能既可以被tc支持。同时,还要编写一个tc的内核实现模块并加载。这样,新的功能,在不重新编译tc,不重启机器的情况下,就得以支持了。这样就很类似浏览器插件的功能了吧:)也是我们期待的结构。

下面看看tc是如何做到这点的,最直接的方法就是查看tc的代码。
查看函数tc_filter_modify的部分代码:

  1. strncpy(k, *argv, sizeof(k)-1);

  2. = get_filter_kind(k);
  3. argc--; argv++;
tc从命令行参数argv中得到filter的类型并存到k中。接下来通过函数get_filter_kinde得到该类型filter的所有操作函数,主要是parse函数。

接下来进入关键的get_filter_kind的函数:

  1. struct filter_util *get_filter_kind(const char *str)
  2. {
  3.     void *dlh;
  4.     char buf[256];
  5.     struct filter_util *q;
     
     /* 这里去遍历已知的filter列表,通过名字查找对应的filter类型 */
  1.     for (= filter_list; q; q = q->next)
  2.         if (strcmp(q->id, str) == 0)
  3.             return q;

     /*
     这部分代码是tc支持自定义扩展的关键代码 
     没有找到,那么就去tc目录下加载对应名字的动态库
     */
  1.     snprintf(buf, sizeof(buf), "%s/f_%s.so", get_tc_lib(), str);
  2.     dlh = dlopen(buf, RTLD_LAZY);
  3.     if (dlh == NULL) {
  4.         /* 
  5.         如果打开该动态库失败,那么就直接去主程序中寻找。
  6.         这样的情况一般是对于tc自身已支持的filter类型。
  7.         */
  8.         dlh = BODY;
  9.         if (dlh == NULL) {
  10.             dlh = BODY = dlopen(NULL, RTLD_LAZY);
  11.             if (dlh == NULL)
  12.                 goto noexist;
  13.         }
  14.     }

     /* 
     打开动态库后,再根据filter的类型名找到对应的name_filter_util符号 
     该符号实际上即为tc的扩展接口,其为一个结构体,定义了filter的操作函数。
     得到该符号后,tc的用户态部分就已经可以支持新的扩展功能了。
     */
  1.     snprintf(buf, sizeof(buf), "%s_filter_util", str);
  2.     q = dlsym(dlh, buf);
  3.     if (== NULL)
  4.         goto noexist;

  5. reg:
  6.     q->next = filter_list;
  7.     filter_list = q;
  8.     return q;
  9. noexist:
  10.     q = malloc(sizeof(*q));
  11.     if (q) {
  12.         memset(q, 0, sizeof(*q));
  13.         strncpy(q->id, str, 15);
  14.         q->parse_fopt = parse_nofopt;
  15.         q->print_fopt = print_nofopt;
  16.         goto reg;
  17.     }
  18.     return q;
  19. }
在上面的代码中,我已经通过注释的方式,解释了tc如何支持扩展的filter类型。

对比iptables和tc的支持扩展的形式,无疑tc更胜一筹,因为无需重新编译iptables就可以支持新的扩展。这都是依赖于dlopen和dlsym来实现的,在我们自己的项目中,也可以采取同样的方式来支持用户自定义的扩展功能。
目录
相关文章
|
6月前
|
Web App开发 容灾 安全
非功能关键知识总结
【2月更文挑战第4天】非功能关键知识总结
276 2
|
13天前
|
JavaScript 搜索推荐 前端开发
DevDocs有哪些功能?
DevDocs有哪些功能?
21 4
|
1月前
|
SQL Oracle 关系型数据库
|
2月前
|
安全 程序员
分享5款在不同场景提供支持的软件
本文介绍了五款实用的软件工具,涵盖静态分析、文件管理、微信空号检测、软件卸载及跨平台共享等领域。其中包括专为逆向工程设计的Cerbero Suite Advanced、现代化文件管理工具tagLyst Next、智能微信空号检测软件燃精灵、专业卸载工具IObit Uninstaller,以及跨平台共享工具Synergy,助力用户高效完成各类任务。
37 1
|
6月前
|
搜索推荐 安全 定位技术
产品服务功能特性
产品服务功能特性
102 3
|
6月前
|
C++
BugProfiler功能使用介绍
BugProfiler功能使用介绍
50 0
|
存储 数据采集 监控
|
数据安全/隐私保护
主要功能
5.1.1 PowerPoint 2010的主要功能 PowerPoint 2010的主要功能是将各种文字、图形图表、音频、视频等多媒体信息以图片的形式展示出来。 在PowerPoint 2010中,将这种制作出的图片叫做幻灯片,而一张张幻灯片组成的文件叫做演示文稿文件。 其默认扩展名为.pptx 模板文件扩展名: potx 放映文件扩展名:ppsx 5.1.2 新建和打开演示文稿 启动PowerPoint 2010后,显示的窗口被称为演示文稿的工作窗口,该窗口主要由快速访问工具栏、选项卡、“幻灯片/大纲”窗格、幻灯片编辑窗格、备注窗功能区、格、任务窗格、状态栏、视图切换按钮和显示比
BXA
|
Web App开发 算法 安全
C++11:必须关注的一个功能
C++11是C++语言的一次重大更新,旨在解决一些C++03语言存在的问题,从而提高其可靠性和可用性
BXA
104 0
|
存储 缓存 监控
如何为从 1 到 10 万用户的应用程序,设计不同的扩展方案?
对于创业公司来说,有用户注册是好事情,但是当用户从零扩展到成千上万之后,Web 应用程序又该如何支持呢?
下一篇
无影云桌面