Visual C++下ACE动态服务配置入门
摘要:
服务动态配置在编写服务端应用在有很明显的优点,本文简要介绍用visual C++ (7.1)
编写ACE动态服务的步骤。
本文适用于ACE初学者。
1. 主进程
1.1 创建主程序
用Viusal Studio创建一空Win32 Console项目,这里命名为GLIVR86ServiceD.注,这里
D表示Daemon,不是Debug。表示我们以后会把这个项目改造为了NT_Service(以后介绍步骤.
1.2 修改项目属性 (Configuation Properties)
1.2.1 为项目新增主文件 GLIVR86ServiceD.cpp,目的是为项目属性中,增加C/C++选项
1.2.1 General 修改程序输出路径$(OutDir)
1.2.2.Debugging Command Arguments: -d, 以调试模式启动
1.2.3 C/C++设置
1.2.3.1 Additional Include Directories /I[path]: $(ACE_ROOT);
1.2.3.2 Code Generation: /MTd ;/MT 调试版选MTd,发行版选 MT
1.2.3.3 Preprocessor:Preprocesor Definitions/D: WIN32;_DEBUG;_CONSOLE;
这是调试版,发行版将_DEBUG改为NDEBUG
1.2.4 链接设置
1.2.4.1 Input: Additinal Dependencise: ACE(d).lib,调试版选aced.lib,
发行版选ace.lib
1.2.4.2 System: SubSystem /subsystem: Console ; (/SUBSYSTEM:CONSOLE)
主程序代码
//
@file: GLIVR86ServiceD.cpp
//
@description: IVR 86业务服务主程序入口
//
@author: jiangtao
//
@version:2.0.0
#include
"
stdafx.h
"
#include
<
memory
>
//
使用 auto_ptr
#include
"
ACE/OS_NS_unistd.h
"
#include
"
ACE/TP_Reactor.h
"
#include
"
ACE/Reactor.h
"
#include
"
ACE/Service_Config.h
"
#include
"
ACE/Thread_Manager.h
"
//
线程池
static
ACE_THR_FUNC_RETURN event_loop (
void
*
arg)
{
ACE_DEBUG((LM_INFO,
"
(%P|%t),event_loop()\n
"
));
ACE_Reactor
*
reactor
=
static_cast
<
ACE_Reactor
*>
(arg);
reactor
->
owner (ACE_OS::thr_self ());
reactor
->
run_reactor_event_loop ();
return
0
;
}
int
ACE_TMAIN (
int
argc, ACE_TCHAR
*
argv[])
{
const
size_t N_THREADS
=
4
;
ACE_TP_Reactor tp_reactor;
ACE_Reactor reactor (
&
tp_reactor);
auto_ptr
<
ACE_Reactor
>
delete_instance(ACE_Reactor::instance (
&
reactor));
if
(ACE_Service_Config::open (argc, argv)
==
-
1
)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT (
"
%p\n
"
),
ACE_TEXT (
"
open
"
)),
1
);
ACE_Thread_Manager::instance ()
->
spawn_n
(N_THREADS, event_loop, ACE_Reactor::instance ());
ACE_Thread_Manager::instance ()
->
wait ();
return
0
;
}
2. 创建被加载的服务的动态链接库
2.1 用Visual Studio创建一个新的项目GLIVR86Service,我们依然从空白的Win32 Console开
始
1.2.1 为项目新增主文件 GLIVR86Service.cpp,目的是为项目属性中,增加C/C++选项
1.2.1 General : Configration Type:改为 动态链接库 Dynamic Library(DLL)
1.2.3.1 Additional Include Directories /I[path]: $(ACE_ROOT);
1.2.3.2 Code Generation: /MTd ;/MT 调试版选MTd,发行版选 MT
1.2.3.3 Preprocessor:Preprocesor Definitions/D:
WIN32;_DEBUG;_WINDOWS;ACE_BUILD_SVC_DLL
这是调试版,发行版将_DEBUG改为NDEBUG
这里,特别注意,要增加 ACE_BUILD_SVC_DLL宏。如果用generate_export_file.pl
生成自定义的export头文件,这个宏也可以自定义
2.2.2 链接器设置
2.2.2.1 Input: Additinal Dependencise: ACE(d).lib,调试版选aced.lib,
发行版选ace.lib
2.2.2.2 System: SubSystem /subsystem: Console ; (/SUBSYSTEM:CONSOLE)
2.2.2.3 General ,Output file:
../GLIVR86ServiceD/GLIVR86ServiceD/GLIVR86ServiceD.dll
这里填写上GLIVR86ServiceD的路径或环境变量Path中指
示的路径,这样可以方便调试
2.2.2.4 Adanced, Import Libaray: $(OutDir)\GLIVR86ServiceD.lib
上面是调试版,发行版可以去掉后缀D,即
$(OutDir)\GLIVR86Service.lib
3.服务的动态链接库实现
3.1 为项目增加两个文件,分别声明和实现服务类工厂
//@file: ServiceFactory.h
//@file: ServiceFactory.cpp
代码分别如下
//
@file: ServiceFactory.h
//
@description: IVR 86业务服务
//
@author: jiangtao
//
@data: 2006-7-3
//
@version:1.0.0
#ifndef SERVICEFACTORY_H
#define
SERVICEFACTORY_H
#include
"
ACE/svc_export.h
"
#include
"
ACE/Service_Config.h
"
#include
"
ACE/Service_Object.h
"
//
声明服务工厂
ACE_SVC_FACTORY_DECLARE (ServiceFactory_T)
class
ACE_Svc_Export ServiceFactory_T :
public
ACE_Service_Object
{
public
:
///
Initializes object when dynamic linking occurs.
virtual
int
init (
int
argc, ACE_TCHAR
*
argv[]);
///
Terminates object when dynamic unlinking occurs.
virtual
int
fini (
void
);
///
Returns information on a service object.
virtual
int
info (ACE_TCHAR
**
info_string, size_t length
=
0
)
const
;
};
#endif
/* SERVICEFACTORY_H */
/*******************************************************************/
//
@file: ServiceFactory.cpp
#include
"
ServiceFactory.h
"
#include
"
ACE/Log_Msg.h
"
//
实现服务工厂
ACE_SVC_FACTORY_DEFINE (ServiceFactory_T)
int
ServiceFactory_T::init(
int
argc, ACE_TCHAR
*
argv[])
{
ACE_DEBUG((LM_INFO,
"
(%P|%t) 服务初始化完成\n
"
));
return
0
;
}
int
ServiceFactory_T::info(ACE_TCHAR
**
strp, size_t length)
const
{
ACE_DEBUG((LM_INFO,
"
ServiceFactory_T::info() \n
"
));
return
0
;
}
int
ServiceFactory_T::fini(
void
)
{
return
0
;
}
5.服务配置文件svc.conf
dynamic IVR86Service Service_Object * GLIVR86Service: _make_ServiceFactory_T() active
6. 运行结果