ACE Service Configurator配置动态服务

1.     导出dll制作步骤

可以参考<<ACE程序员指南>>p25,dll制作,在此基础上,增加6和7

1)制定dll名称,例如AgentService(.dll)

2)用generate_export_file.pl AgentService 生成自定义的AgentServiceExport.h头文件

3)在dll的工程main函数所在的源文件包含所程程的AgentServiceExprot.h头文件

4)  在进行类的声明时,在class关键字和类名之间插入关键字AgentService_Export 
注:若本身就是dll工程,则不需要该关键字

5)在编译DLL的源文件时,定义宏AgentService_BUILD_DLL

6)  在DLL的源文件中加入如下宏
ACE_FACTORY_DEFINE (AgentService, AgentServer)
AgentService为dll名称,AgentServer为dll中具体实现类的名称

7)编写svc.conf文件,供调用exe使用,格式为
dynamic AgentService Service_Object * AgentService:_make_AgentServer() "AgentServer.xml"


2.     调用者exe制作步骤

1)如果是console,则main函数中举例如下

#include <WINSOCK2.H>
#include <atlbase.h>
#include <ace/OS.h>
#include <ace/Object_Manager.h>
#include <ace/Service_Config.h>
#include <ace/Service_Repository.h>
#include <ace/Service_Object.h>
 
#include <windows.h>
 
int main(int argc, char* argv[])
{
CoInitialize(NULL);
    ACE::init();
   
    ACE_TCHAR path[MAX_PATH];
    ACE_TCHAR cwd[MAX_PATH];
 
    ::GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
    //LogEvent(path);
    ACE_TCHAR* ptr = path + ACE_OS::strlen(path);
    while(*ptr != TEXT('/') && *ptr != TEXT('//') && *ptr != TEXT(':')){
        --ptr;
        if(ptr == path) {
            break;
        }
    }
    *(++ptr) = '/0';
 
    //::SetCurrentDirectory(path);
 
    ACE_OS::getcwd(cwd, MAX_PATH);
    ACE_OS::chdir(path);
 
    int argcSvc = 4;
    ACE_TCHAR *argvSvc[4] = {
        ACE_TEXT("OnmiService"),
        ACE_TEXT("-d"),
        ACE_TEXT("-f"),
        ACE_TEXT("svc.conf")
    };
//  argv[3] = path;
    if(ACE_Service_Config::open(argcSvc, argvSvc) == -1) {
        ACE_DEBUG((LM_ERROR, ACE_TEXT("start ace_service_config failed/n")));
    }
 
while(1){
        cin >> ch;
        if(ch == 'q' || ch == 'Q')
        {
            ACE_DEBUG ((LM_INFO, ACE_TEXT (" | %t | %N %l | Stop OnmiConsole!/n")));
            ACE_Service_Config::fini_svcs();
            break;
        }
}
    CoUninitialize();
    return 0;
}

2 )如果是基于 MFC dialog 应用,则需要创建一线程启动起 dll

m_pConfigService = DYNAMIC_DOWNCAST(CConfigService, AfxBeginThread(RUNTIME_CLASS(CConfigService)));
    if(m_pConfigService == NULL)
    {
        AfxMessageBox("Start Agent Service failed");
        return -1;
    }

class CConfigService : public CWinThread
{
}
CConfigService 的实现,参考AGSD工程中ConfigService.hConfigService.cpp文件

///
//ConfigService.h
 
#pragma once
 
// CConfigService
 
class CConfigService : public CWinThread
{
    DECLARE_DYNCREATE(CConfigService)
 
protected:
    CConfigService();           // 动态创建所使用的受保护的构造函数
    virtual ~CConfigService();
 
public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
    virtual int Run( );
 
    BOOL Stop(void);
 
    FILE * GetOutStream();
 
    BOOL m_isRun;
 
protected:
    DECLARE_MESSAGE_MAP()
 
private:
    FILE * m_out;
 
};
 
 
 

// ConfigService.cpp : 实现文件
//
 
#include "stdafx.h"
#include "AGSD.h"
 
#include "ConfigService.h"
 
#include <ace/OS.h>
#include <ace/Object_Manager.h>
#include <ace/Service_Config.h>
#include <ace/Service_Repository.h>
#include <ace/Service_Object.h>
#include <ace/Reactor.h>
 
 
// CConfigService
 
IMPLEMENT_DYNCREATE(CConfigService, CWinThread)
 
CConfigService::CConfigService()
: m_out(NULL)
{
}
 
CConfigService::~CConfigService()
{
}
 
BOOL CConfigService::InitInstance()
{
    ACE::init();
   
    errno_t err = freopen_s( &m_out, "freopen.out", "w+", stdout );
    if(err != 0)
    {
        AfxMessageBox(TEXT("Redirection error!"));
    }
 
    return TRUE;
}
 
int CConfigService::Run( )
{
    ACE_TCHAR path[MAX_PATH];
    ACE_TCHAR cwd[MAX_PATH];
 
    ::GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
    //LogEvent(path);
    ACE_TCHAR* ptr = path + ACE_OS::strlen(path);
    while(*ptr != TEXT('/') && *ptr != TEXT('//') && *ptr != TEXT(':'))
    {
        --ptr;
        if(ptr == path) {
            break;
        }
    }
    *(++ptr) = '/0';
 
    //::SetCurrentDirectory(path);
 
    ACE_OS::getcwd(cwd, MAX_PATH);
    ACE_OS::chdir(path);
 
    int argcSvc = 4;
    ACE_TCHAR *argvSvc[4] = {
        ACE_TEXT("OnmiService"),
        ACE_TEXT("-d"),
        ACE_TEXT("-f"),
        ACE_TEXT("svc.conf")
    };
   
    if(ACE_Service_Config::open(argcSvc, argvSvc) == -1) {
        ACE_DEBUG((LM_ERROR, ACE_TEXT("start ace_service_config failed/n")));
    }
   
    m_isRun = TRUE;
    return ACE_Reactor::instance()->run_reactor_event_loop ();
}
 
int CConfigService::ExitInstance()
{
    freopen( "CON", "w", stdout );
 
    return CWinThread::ExitInstance();
}
 
BEGIN_MESSAGE_MAP(CConfigService, CWinThread)
END_MESSAGE_MAP()
 
 
// CConfigService 消息处理程序
BOOL CConfigService::Stop(void)
{
    ACE_Reactor::instance()->end_event_loop ();
    return 0;
}
 
FILE * CConfigService::GetOutStream()
{
    return stdout;
}

3.     解释说明

3.1. 建立工程说明

1)若本身就是dll工程的话,且有DllMain入口函数,则不需要对AgentServer类进行导出声明 AGENTSERVICE_Export;

2)只有从console改造过来的工程,而且没有main函数或者是DllMain函数,则需要对AgentServer类进行导出声明,声明符号为 AGENTSERVICE_Export,具体的符号需要使用$ACE_ROOT/bin/generate_export_file.pl AgentService 命令进行导出(AgentServcie为dll名称)

 

3.2. 宏ACE_FACTORY_DEFINE(CLS,SERVICE_CLASS)

  对于ACE_FACTORY_DEFINE (AgentService, AgentServer)宏的解释

  AgentService是:  CLS-是程序/库用来导入/导出声明的标识符. 取决于使用上述命令生成Export头文件时传入的参数,并与参数保持一致。

  AgentServer是: SERVICE_CLASS是从ACE_Service_Object派生的类的名称,它会在服务初始化时被实例化,并于内部需要导出的实现类名保持一致。

 

3.3. 配置文件svc.conf

svc.conf格式

dynamic ident Service_Object * lib-pathname : factory-func() [active|inactive] [parameters]

实例

dynamic AgentService Service_Object * AgentService:_make_AgentServer() "AgentServer.xml"

其中AgentService为标识符,可以起另外的名字

AgentService代表dll名称

_make_AgentServer()中的AgentServer为dll中实现类的名称

"AgentServer.xml"为参数名称

4.     举例

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. 
运行结果

5. 另一举例配置动态服务

ACE Service Configurator框架更强大的功能表现在配置动态服务上。如果在运行时收到指示,动态服务器可以从共享库(DLL)中动态加载。这种能力允许你在运行时替换服务,从而提供极大的灵活性。

ACE Service Configurator框架简化了全部的冗余工作。我们只需要按照设计规格实现我们需要的服务,把它载入到一个动态链接库中,编辑配置文件即可。换句话说:我们只需要创建一个合乎规格的动态链接库,然后在上例的svc.conf里面添加一两行指令,再次运行该程序即可加载此动态服务,我们甚至不需要对该程序进行重新编译。

动态链接库Mydll

5.1.    确定我们将要设计的动态链接库名字为Mydll

5.2.    运行$ACE_ROOT/bin/generate_export_file.pl Mydll,将输出写入Mydll_Export.h中去。

设计我们的服务的类,在类的源文件中包含该文件,并将关键字

#i nclude “Mydll_Export.h”
 
class  Mydll_Export MyDynamicObj : public ACE_Service_Object 
{
public:
       MyDynamicObj();
       virtual ~MyDynamicObj();
 
       virtual int init (int argc, ACE_TCHAR *argv[])
       {
              printf("MyDynamicObj::init------/n");
              return 0;
       }
 virtual int fini()
       {
        
              printf("MyDynamicObj::fini-----/n");
              return 0;
       } 
};
 
ACE_FACTORY_DEFINE(Mydll,MyDynamicObj)

5.3. 编译,并在svc.conf里面加入如下指令,再运行,发现动态服务已被加载、移除。

dynamic MyDynamicObj Service_Object* Mydll:_make_MyDynamicObj() ""
 remove MyDynamicObj

转贴:http://blog.csdn.net/badmouse/article/details/3993439
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Configurator是一种用于配置Vector的autosar工具的工具。它允许用户通过添加配置文件来更改或扩展生成的代码。用户可以在生成的模块配置文件的末尾添加用户配置文件的内容,以便个性化定制代码。然而,需要注意的是,用户配置文件可能会导致软件模块出现故障,因此必须小心使用。 对于CanTp模块,可以使用User Config File来进行配置。点击CanTp模块的User Config File,可以在Properties中找到有关该配置文件的简单介绍。该配置文件的路径是./Config/Test_Config/CanTp/CanTp.txt,表示在工程目录的Config文件夹下新建Test_Config文件夹,再在Test_Config文件夹下新建CanTp文件夹,并在CanTp文件夹中添加CanTp.txt文件。用户可以根据需要手动添加这些文件夹和文件。 另外,在Dcm模块的DcmDslServiceRequestSupplierNotification模块中,可以通过右击选择"create xxx container"来创建相应的容器。 举例来说,如果需要在11服务中添加NRC22条件(车速小于3km/h)的检测,当车速大于3km/h时,ECU接收到11 01请求,则响应NRC22。可以在相应的配置文件中进行设置。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span> #### 引用[.reference_title] - *1* *2* [Davinci Configurator之User Config File配置功能](https://blog.csdn.net/weixin_42412049/article/details/123610085)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* *4* [[Davinci Configurator 配置] 实现功能寻址不响应、关闭抑制肯定响应、NRC否定响应](https://blog.csdn.net/fly_xiaocaibi88/article/details/126544389)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值