【slighttpd】基于lighttpd架构的Server项目实战(10)—插件&动态库
2016-02-12 13:45
615 查看
上一节我们介绍了状态机,本节我们将添加插件模块,之后就可以根据公共接口来开发插件,而我们的server则只需要通过状态机调用相应阶段的公共函数,无需关心插件的实现细节。我们的插件将以动态库so的形式来加载。
本项目的插件接口对应于状态机的阶段,每个阶段提供一个函数:
插件
我们的插件类将作为一个基类,成员函数作为虚函数,之后由插件开发者继承、实现。本项目的插件接口对应于状态机的阶段,每个阶段提供一个函数:
[code]/************************************************************************* > File Name: plugin.h > Author: Jiange > Mail: jiangezh@qq.com > Created Time: 2016年02月10日 星期三 18时46分22秒 ************************************************************************/ #ifndef _PLUGIN_H #define _PLUGIN_H class Worker; class Connection; typedef enum { PLUGIN_READY, PLUGIN_NOT_READY, PLUGIN_ERROR } plugin_state_t; class Plugin { public: Plugin(); virtual ~Plugin(); virtual bool Init(Connection *con, int index); virtual bool RequestStart(Connection *con, int index); virtual bool Read(Connection *con, int index); virtual bool RequestEnd(Connection *con, int index); virtual bool ResponseStart(Connection *con, int index); virtual plugin_state_t Write(Connection *con, int index); virtual bool ResponseEnd(Connection *con, int index); virtual void Close(Connection *con, int index); virtual bool Trigger(Worker* worker, int index); virtual bool LoadPlugin(Worker* worker, int index); virtual void FreePlugin(Worker* worker, int index); typedef Plugin* (*SetupPlugin)(); typedef void (*RemovePlugin)(Plugin *plugin); SetupPlugin setup_plugin; RemovePlugin remove_plugin; void* plugin_data; void* plugin_so; int plugin_index; bool plugin_is_loaded; }; #endif
动态库加载
[code]const char *path = so_path; //动态库so的路径 /* dlopen()函数以指定模式打开指定的动态链接库文件, * 并返回一个句柄给dlsym()的调用进程。 * 使用dlclose()来卸载打开的库。 * 头文件#include <dlfcn.h> * RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析 * (只对函数引用有效,对于变量引用总是立即解析)。 */ void *so = dlopen(path, RTLD_LAZY); if (!so) { std::cerr << dlerror() << std::endl; return false; } /* void* dlsym(void* handle,const char* symbol) * 根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。 * 使用这个函数不但可以获取函数地址,也可以获取变量地址。 * handle:由dlopen打开动态链接库后返回的指针; * symbol:要求获取的函数或全局变量的名称。 * SetupPlugin和RemovePlugin是插件模块中的函数; * SetupPlugin返回一个动态分配的插件对象; * RemovePlugin释放插件对象的内存空间。 */ Plugin::SetupPlugin setup_plugin = (Plugin::SetupPlugin)dlsym(so, "SetupPlugin"); Plugin::RemovePlugin remove_plugin = (Plugin::RemovePlugin)dlsym(so, "RemovePlugin"); if (!setup_plugin || !remove_plugin) { std::cerr << dlerror() << std::endl; dlclose(so); return false; } //根据上面取得的函数句柄,获取插件对象 Plugin *plugin = setup_plugin(); if (!plugin) { //卸载打开的库 dlclose(so); return false; } //…… return true;
相关文章推荐
- 网络层提供的两种服务——虚电路服务和数据报服务
- 什么是神经网络或者微粒群算法所说的陷入 局部极小值?局部极小值是什么?
- bzoj:1834: [ZJOI2010]network 网络扩容
- MirrorNetwork 基于jmdns和netty的android网络通信开源库
- Alex-Word-Filter-MFC网络版java客户端发布
- TCP流量控制
- TCP状态转换
- http VS https
- 从贝叶斯方法谈到贝叶斯网络
- 解决win10下WIFI无法连接到网络
- TCP/IP协议模型详解
- 深度学习与计算机视觉系列(10)_细说卷积神经网络
- VirtualBox虚拟机网络环境解析和搭建-NAT、桥接、Host-Only、Internal、端口映射
- Linux网络编程 -- 网络模型与通信过程
- 网络请求 NSURLsession(get、post、下载、上传)
- 初始HTTP和CSS第一篇span的练习
- 87
- ubuntu的网络配置
- c#之socket网络编程流程
- 网络缓存的逻辑