插件化软件设计的问题

huangzhtao 2011-06-07 06:14:24
前两天看到一篇帖子讨论关于插件化软件设计的
如何做“插件化软件”,“模块化软件”设计。

正好手边也需要类似的功能,看完后挺有启发。

针对我目前的需求,还有一些问题没有解决,需要向大家请教的。
软件的功能如下:
1. 是一个硬件采集程序。
2. 主程序主要负责界面绘制和加载各功能DLL。
3. 其中有一个DLL主要负责采集设备的初始化,生成一个设备对象。
4. 其它有多个DLL用于针对采集的数据做处理,每个DLL一个处理功能,可以循环调用每个DLL的功能做处理,处理结果加到一个队列中。

主要有以下问题:
1. 以前只做过简单的DLL调用,基本调一个函数就完了。这次需要在多个DLL中共享数据,还有类对象实例,看了些文章介绍,其中提到类对象的话在DLL间共享的话可能会有问题,微软MSDN就不推荐共享C++类 http://msdn.microsoft.com/zh-cn/library/h90dkhs0(v=vs.80).aspx
2. 一个DLL负责设备初始化,设备对象是以C++类形式定义的,同样也是第一个问题;设备有多种不同设备,为了适应不同设备需要和以后添加设备,这个共享的对象应该怎么定义才能为以后的升级和复用带来方便(不影响使用该对象的DLL)。
3. 上面4中的方法,首先由初始化DLL初始化设备,然后循环控制是否应该交给主程序,那样的话在主程序中还是要调用设备对象的方法,不知该如何实现。
...全文
177 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangzhtao 2011-07-04
  • 打赏
  • 举报
回复
多谢了,结贴给分。
huangzhtao 2011-06-07
  • 打赏
  • 举报
回复
刚把文章看完,还需要消化下。

顺便问下,由初始化DLL初始化设备,然后循环控制是否应该交给主程序,那样的话在主程序中还是要调用设备对象的方法,不知道好不好实现。
ryfdizuo 2011-06-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 huangzhtao 的回复:]

设备对象怎么共享,是个类对象,处理上一样吗?
[/Quote]
设备对象可以作为RegisterPlugin参数传进去,
extern "C" PLUGIN_API void RegisterPlugin(VPFactory& factory);
huangzhtao 2011-06-07
  • 打赏
  • 举报
回复
设备对象怎么共享,是个类对象,处理上一样吗?
huangzhtao 2011-06-07
  • 打赏
  • 举报
回复
多谢dizuo,正在看那篇文章。
ryfdizuo 2011-06-07
  • 打赏
  • 举报
回复
之前有实现过类似的设计:
#ifndef PLUGIN_API
#define PLUGIN_API __declspec(dllexport)
#endif

extern "C" PLUGIN_API void RegisterPlugin(VPFactory& factory){
process... results;
factory.push_back(results);
}
extern "C" PLUGIN_API void UnReisterPlugin(VPFactory& factory){
factory.erase(results);
}

dll插件中提供两个接口:注册和注销。
按照你软件功能4所说,可以把处理队列作为函数参数,dll中处理完的结果添加到队列中,队列是传引用的形式。

主程序中定义保存处理结果的队列:factory。
加载dll的时候通过调用接口函数,将各个插件处理的结果放到factory中:

// 遍历指定文件夹下的dll插件。
void MainWindow::setupFactory()
{
//get the program's directory
wchar_t dir [MAX_PATH];
::GetModuleFileName (NULL, dir, MAX_PATH);

//eliminate the file name (to get just the directory)
wchar_t* p = ::wcsrchr (dir, '\\');
*(p + 1) = 0;

//find all DLLs in the plugins subdirectory
wchar_t search_parms [MAX_PATH];
::wcscpy_s (search_parms, MAX_PATH, dir);
::wcscat_s (search_parms, MAX_PATH, L"plugins\\*.dll");

WIN32_FIND_DATA find_data;
HANDLE h_find = ::FindFirstFile (search_parms, &find_data);
BOOL f_ok = TRUE;
while (h_find != INVALID_HANDLE_VALUE && f_ok)
{
//load each DLL and determine whether it is exporting the functions we care about
wchar_t plugin_full_name [MAX_PATH];
::wcscpy_s (plugin_full_name, MAX_PATH, dir);
::wcscat_s (plugin_full_name, MAX_PATH, L"plugins\\");
::wcscat_s (plugin_full_name, MAX_PATH, find_data.cFileName);

HMODULE h_mod = ::LoadLibrary(plugin_full_name);
if (h_mod != NULL)
{
// 保存插件列表
loadedPlugins.push_back(h_mod);

// 注册插件
PLUGIN_FUNC_PTR p_register_function =
(PLUGIN_FUNC_PTR) ::GetProcAddress (h_mod, "RegisterPlugin");

if (p_register_function != NULL)
{
// 将结果放到factory单件实例中。
(*p_register_function)( VPFactorySingleton::Instance() );
}
}

//go for the next DLL
f_ok = ::FindNextFile (h_find, &find_data);
}

}


google:
A simple plug-in architecture pattern for C++ applications on Win32

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧