首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

插件化软件设计的有关问题

2012-12-15 
插件化软件设计的问题前两天看到一篇帖子讨论关于插件化软件设计的如何做“插件化软件”,“模块化软件”设计。

插件化软件设计的问题
前两天看到一篇帖子讨论关于插件化软件设计的
如何做“插件化软件”,“模块化软件”设计。  

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

针对我目前的需求,还有一些问题没有解决,需要向大家请教的。
软件的功能如下:
  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初始化设备,然后循环控制是否应该交给主程序,那样的话在主程序中还是要调用设备对象的方法,不知该如何实现。

[最优解释]
之前有实现过类似的设计:

#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 
------其他解决方案--------------------


http://www.abstraction.net/ViewArticle.aspx?articleID=67
[其他解释]
多谢dizuo,正在看那篇文章。
[其他解释]
设备对象怎么共享,是个类对象,处理上一样吗?
[其他解释]

引用:
设备对象怎么共享,是个类对象,处理上一样吗?

设备对象可以作为RegisterPlugin参数传进去,
extern "C" PLUGIN_API void RegisterPlugin(VPFactory& factory);
[其他解释]
刚把文章看完,还需要消化下。

顺便问下,由初始化DLL初始化设备,然后循环控制是否应该交给主程序,那样的话在主程序中还是要调用设备对象的方法,不知道好不好实现。
[其他解释]
路过,学习中。
[其他解释]
多谢了,结贴给分。

热点排行
Bad Request.