关于ACE可以实现运行时动态相应事件的原理请参考:
这里按下Ctrl+C来重新配置dll服务使用了:
本文源代码下载:http://pan.baidu.com/s/1gdgmV9D代码超级简单,直接编译运行Debug》Start Without Debuging
的方法实现运行相应键盘输入Ctrl+C,而重新配置则使用了ACE_Service_Config::reconfigure()方法,只要将此方法放到相应事件的处理程序(handle_signal)部分即可。如果要使ACE_Service_Config能够从配置文件加载服务,则服务必须是dll,而且服务内的类必须继承ACE_Service_Object,将要加载的服务放到重写了ACE_Service_Object的方法中之后,在配置文件中写配置指令就会和这里的方法一一对应。从而实现读取配置文件来使用dll中的不同功能。
在系统初始化的时候由ACE_Service_Config::open加载配置文件svc.conf中的配置信息
dynamic ParseProtocolA Service_Object * ParseProtocolA:_make_ParseProtocolA() ""
dynamic ParseProtocolB Service_Object * ParseProtocolB:_make_ParseProtocolB() ""
suspend ParseProtocolB
suspend ParseProtocolA
remove ParseProtocolA
这里的ParseProtocolA和ParseProtocolB是两个dll,生成这两个dll需要两个工程分别如下:
注意创建DLL工程的时候要设置:
Setting->C/C++->Category(general)->preprocessor definitions: YOURCLASSNAME_EXPORTS,ACE_BUILD_SVC_DLL
注意:这三个工程都需要完整的使用ACE的功能,所以这三个工程都要:
ACE在VS2010下快速配置三部曲:(这里假设你的ACE目录为E:\ACE_wrappers,即从网上下的ACE完整VS包)
(1)Properties》Configuration Properties》VC++ Directories》Include Directories》E:\ACE_wrappers
(2)Properties》Configuration Properties》VC++ Directories》Library Directories》E:\ACE_wrappers\lib
(3)Properties》Configuration Properties》Linker》Input》Additional Dependencies》ACEd.lib
详细参考博客:http://blog.csdn.net/calmreason/article/details/38082009
除此之外,每个工程还需设置:
Manifest Tool》Input and OutPut》Embed Manifest》NO
ParseProtocolA工程,工程类型为dll
ParseProtocolA.h
#ifndef PARSEPROTOCOLA_H
#define PARSEPROTOCOLA_H
#include <iostream>
#include "ace/Service_Object.h"
#include "ace/svc_export.h"
using namespace std;
class ACE_Svc_Export ParseProtocolA : public ACE_Service_Object
{
public:
ParseProtocolA(void);
virtual ~ParseProtocolA(void);
virtual int init (int argc, char *argv[])
{
cout<<"Parse Protocol A Obj::init"<<endl;
return 0;
}
virtual int suspend()
{
cout<<"Parse Protocol A Obj::suspend"<<endl;
return 0;
}
virtual int resume()
{
cout<<"Parse Protocol A Obj::resume"<<endl;
return 0;
}
virtual int fini()
{
cout<<"Parse Protocol A Obj::fini"<<endl;
return 0;
}
};
ACE_SVC_FACTORY_DECLARE(ParseProtocolA)
#endif
ParseProtocolA.cpp
#include "ParseProtocolA.h"
ParseProtocolA::ParseProtocolA(void)
{
}
ParseProtocolA::~ParseProtocolA(void)
{
}
ACE_SVC_FACTORY_DEFINE(ParseProtocolA)
注意:vs设置》C/C++》Preprocessor》Preprocessor Definitions》添加》PARSEPROTOCOLA_EXPORTS
编译出错:LINK : error LNK2001: unresolved external symbol __DllMainCRTStartup@12,设置项目属性Linker》Advanced》No Entry Point》Yes
ParseProtocolB工程,工程类型也为dllParseProtocolB.h
#ifndef PARSEPROTOCOLB_H
#define PARSEPROTOCOLB_H
#include <iostream>
#include "ace/Service_Object.h"
#include "ace/svc_export.h"
using namespace std;
class ACE_Svc_Export ParseProtocolB: public ACE_Service_Object
{
public:
ParseProtocolB(void);
virtual ~ParseProtocolB(void);
virtual int init (int argc, char *argv[])
{
cout<<"Parse Protocol B Obj::init"<<endl;
return 0;
}
virtual int suspend()
{
cout<<"Parse Protocol B Obj::suspend"<<endl;
return 0;
}
virtual int resume()
{
cout<<"Parse Protocol B Obj::resume"<<endl;
return 0;
}
virtual int fini()
{
cout<<"Parse Protocol B Obj::fini"<<endl;
return 0;
}
};
ACE_SVC_FACTORY_DECLARE(ParseProtocolB)
#endif
ParseProtocolB.cpp
#include "ParseProtocolB.h"
ParseProtocolB::ParseProtocolB(void)
{
}
ParseProtocolB::~ParseProtocolB(void)
{
}
ACE_SVC_FACTORY_DEFINE(ParseProtocolB)
注意:vs设置》C/C++》Preprocessor》Preprocessor Definitions》添加》PARSEPROTOCOLB_EXPORTS
最后创建第三个项目UseService来动态的调用前面的两个dll服务
其中conf文件如下
conf文件内容
main.cpp
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
#include <iostream>
#include "ace/Service_Config.h"
#define SIGINT 2 //按下control + c (系统已有定义的信号量)
class SignalHandler : public ACE_Event_Handler
{
public:
//构造函数时注册信号,当此信号发生时(用户按下Ctrl+C时)被ACE_Reactor捕捉到
//同事调用此类的handle_signal方法
SignalHandler()
{
reactor()->instance()->register_handler(SIGINT,this);
}
int handle_signal(int signum, siginfo_t*,ucontext_t*) //处理信号
{
switch(signum)
{
case SIGINT:
{
std::cout<<"You pressed SIGINT(Ctrl+C)\n";
ACE_Service_Config::reconfigure();
}
break;
}
return 0;
}
};
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
if (ACE_Service_Config::open (argc, argv) == -1)
ACE_ERROR_RETURN ((LM_ERROR,"%p\n","ACE_Service_Config::open"),-1);
//对不起看官:下面创建对象的这一句话在之前没有加上,
//今天发现了特意加上,因为我自己也因为这一句话没写而反复调试了多遍
//2014/4/1
SignalHandler* signalhandler = new SignalHandler();
ACE_Reactor::instance ()->run_reactor_event_loop();
return 0;
}
修改配置文件如下
dynamic ParseProtocolA Service_Object * ParseProtocolA:_make_ParseProtocolA() ""
dynamic ParseProtocolB Service_Object * ParseProtocolB:_make_ParseProtocolB() ""
suspend ParseProtocolB
suspend ParseProtocolA
remove ParseProtocolA
remove ParseProtocolB
按Ctrl+C
新的输出如下:可见最后一行多了remove B的相应信息