slighttpd基于lighttpd架构的Server项目实战(10)—插件&动态库
Posted jiange_zh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了slighttpd基于lighttpd架构的Server项目实战(10)—插件&动态库相关的知识,希望对你有一定的参考价值。
上一节我们介绍了状态机,本节我们将添加插件模块,之后就可以根据公共接口来开发插件,而我们的server则只需要通过状态机调用相应阶段的公共函数,无需关心插件的实现细节。我们的插件将以动态库so的形式来加载。
插件
我们的插件类将作为一个基类,成员函数作为虚函数,之后由插件开发者继承、实现。
本项目的插件接口对应于状态机的阶段,每个阶段提供一个函数:
/*************************************************************************
> File Name: plugin.h
> Author: Jiange
> Mail: [email protected]
> 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
动态库加载
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;
以上是关于slighttpd基于lighttpd架构的Server项目实战(10)—插件&动态库的主要内容,如果未能解决你的问题,请参考以下文章
slighttpd基于lighttpd架构的Server项目实战—http-parser
slighttpd基于lighttpd架构的Server项目实战—状态机机制回顾
slighttpd基于lighttpd架构的Server项目实战(10)—插件&动态库