博客
关于我
VC++实现应用程序对插件的支持
阅读量:797 次
发布时间:2023-02-26

本文共 2309 字,大约阅读时间需要 7 分钟。

插件技术与应用程序扩展

插件接口标准与设计思路

支持插件的应用程序通常将插件文件集中存放于特定目录下。程序运行时会首先搜索该目录,发现插件后将其加载到应用程序中,程序终止时负责释放插件资源。插件的形式可以是独立可执行文件、动态链接库或其他文件格式,以便于灵活使用。本文以动态链接库形式实现插件管理,因其支持灵活的插件装载和调用。

主程序无法事先预知插件的数量及功能,因此需要与插件之间建立统一的接口标准。插件与主程序通过标准的DLL导出函数交互,主要用于插件对象的创建。以下是常见的接口定义:

BOOL Plug_CreateObject(void ** pobj)

插件类通过派生自基类CPlugBase来实现主要功能,如获取插件图标、功能接口调用和资源释放等。基类CPlugBase的结构如下:

class CPlugBase
public:  
CPlugBase(){};
virtual HICON GetIcon() = 0;
virtual void Interface(int k) = 0;
virtual void Release() = 0;

为了方便管理插件对象,主程序使用模板类CArray存储插件信息。插件管理结构PLUG_ST记录插件类指针和动态链接库句柄,其定义如下:

typedef struct
PLUG_ST, *LPPLUG_ST  
{
CPlugBase * pObj;
HINSTANCE hIns;
}

插件图标在工具条按钮上显示,主程序通过插件的GetIcon()函数获取图标句柄绘制按钮。插件按钮的命令响应使用ON_COMMAND_RANGE宏实现,覆盖ID范围内的命令。

普通应用程序插件支持

任何普通应用程序都可以通过编码实现插件支持。插件搜索逻辑通常位于主框架类中,首先检查PLUGINS子目录下是否存在插件动态链接库。如果存在则加载插件并添加到插件管理数组中。插件装载过程如下:

PLUG_ST stPs;
ZeroMemory(&stPs, sizeof(stPs));  
stPs.hIns = LoadLibrary(szPlug);
PFN_Plug_CreateObject pFunc = GetProcAddress(stPs.hIns, _T("Plug_CreateObject"));
if (pFunc((void **)&stPs.pObj))  
m_arrPlugObj.Add(stPs);

插件图标提取并绘制到工具条按钮,按钮资源ID从ID_PLUG_POINTER开始递增。插件按钮的命令响应函数使用ON_COMMAND_RANGE实现,具体处理如下:

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)  
ON_COMMAND_RANGE(ID_PLUG_POINTER, ID_PLUG_POINTER+256, OnPlugHit)
void CMainFrame::OnPlugHit(UINT nID)  
{
int id = nID - ID_PLUG_POINTER;  
if (id >= 0 && id < m_arrPlugObj.GetSize())
{
if (m_arrPlugObj[id].pObj)  
m_arrPlugObj[id].pObj->Interface(id);

插件资源释放

在程序终止前,确保释放所有插件资源。插件对象释放包括调用Release()方法和释放动态链接库句柄,最后清空插件管理数组:

for (int i = 0; i < m_arrPlugObj.GetSize(); i++)  
{
if (m_arrPlugObj[i].pObj)  
m_arrPlugObj[i].pObj->Release();
if (m_arrPlugObj[i].hIns)  
FreeLibrary(m_arrPlugObj[i].hIns);
m_arrPlugObj.RemoveAll();

插件制作

插件制作涉及创建动态链接库,需注意以下几点:首先确保插件图标在资源中正确引入,并设置为“Use MFC in a Static Library”以便在编译时将资源打包到插件模块。其次,插件必须遵循主程序的接口标准,主要通过导出函数实现。常见的导出函数包括:

LIBRARY "PlugA"
EXPORTS  
Plug_CreateObject @1

导出函数Plug_CreateObject负责创建插件对象:

BOOL WINAPI Plug_CreateObject(void ** pobj)
{
*pobj = new CPlugA; return *pobj != NULL;

插件类CPlugA继承自CPlugBase,实现插件特定功能,如图标获取和功能接口调用。

转载地址:http://tfvfk.baihongyu.com/

你可能感兴趣的文章
Oracle数据库入门——初级系列教程
查看>>
oracle数据库包package小例子
查看>>
UBUNTU 添加删除用户
查看>>
Oracle数据库备份与还原
查看>>
Oracle数据库学习(三)
查看>>
Oracle数据库安装成功后,忘记解锁账户和设置密码
查看>>
TypeError: create_purple() 接受 0 个位置参数,但给出了 2 个
查看>>
Oracle数据库异常--- oracle_10g_登录em后,提示java.lang.Exception_Exception_in_sending_Request__null或Connection
查看>>
Oracle数据库异常---OracleDBConsoleorcl无法启动
查看>>
oracle数据库异常---SP2-1503: 无法初始化 Oracle 调用界面 SP2-1503: 无法初始化 Oracle 问题的解决办法
查看>>
Oracle数据库性能调优
查看>>
oracle数据库核心笔记
查看>>
oracle数据库笔记---oracleweb视图使用流程,及plsql安装
查看>>
oracle数据库笔记---pl/sql的基础使用方法
查看>>
Transformer 架构解释
查看>>
Oracle数据库表空间 数据文件 用户 以及表创建的SQL代码
查看>>
oracle数据库零碎---Oracle Merge 使用,表中存在数据就修改,没有数据自动添加
查看>>
Oracle数据库验证IMP导入元数据是否会覆盖历史表数据
查看>>
oracle数据插入表,oracle同时向多表插入数据
查看>>
oracle数据类型和对应的java类型
查看>>