采用ACE实现C++中的Plugin

    技术2022-05-11  65

             本文描述小鸡射手采用ACE的Service Configurator Framework实现C++的plugin机制。

             首先,定义一个export头文件,可以从/examples/APG/Svc_Config的HASTATUS_export.h复制修改。头文件定义如下:

    #include  " ace/OS.h " #include  " ace/Service_Object.h " #include  " TEST_export.h " #include  " ITimerListener.h " class  TEST_Export TestDynamic :  public  ACE_Service_Object,  public  ITimerListener {public:    virtual int init (int argc, ACE_TCHAR *argv[]);    virtual int fini (void);    virtual int info (ACE_TCHAR **str, size_t len) const;    virtual void  OnTimer(const int eventID, const void* data);} ;

            OnTimer是ITimerListener中定义的一个业务函数。TestDynamic类的实现如下:

    #include  " ace/Get_Opt.h " #include  " Test_Dynamic.h " int  TestDynamic::init ( int  argc, ACE_TCHAR  * argv[]) {    ACE_DEBUG ((LM_DEBUG, "Initializing... "));    // 读取配置文件中的配置    ACE_Get_Opt opt(argc, argv, "s:p:"0);    for(int c; (c=opt()) != -1; ) {        switch(c) {            case 's' :     ACE_DEBUG((LM_DEBUG, "Server is %s. ", opt.opt_arg()));    break;             case 'p':      ACE_DEBUG((LM_DEBUG, "Port is %d. ", atoi(opt.opt_arg())));    break;             }       }       return 0;} int  TestDynamic::fini ( void ) {    ACE_DEBUG ((LM_DEBUG, "Finishing... "));    return 0;} int  TestDynamic::info(ACE_TCHAR  ** str, size_t len)  const {    static char info[512= {0};    sprintf(info, "test dynamic.");    *str = info;    return strlen(info);} void  TestDynamic::OnTimer( const   int  eventID,  const   void *  data) {    ACE_DEBUG ((LM_DEBUG, "TimerID is %d ", eventID));} //  采用宏定义Plugin ACE_FACTORY_DEFINE (TEST, TestDynamic)

            在VC中编译的话,注意增加预编译定义TEST_BUILD_DLL,并将RTTI打开。Plugin DLL就定义好了,配置文件svc.conf定义如下:

    dynamic Test_Dynamic_Service Service_Object  *  TestDynamic:_make_TestDynamic()  " -s 127.0.0.1 -p 8018 "

           在给出主程序前,先定义根据服务名得到plugin实例的help函数,定义如下:

    #include  " ace/Service_Repository.h " #include  " ace/Service_Types.h " template  < class  DLL_SERVICE_TYPE > class  DynamicService {public:    static DLL_SERVICE_TYPE* Instance(const char* const name)    {        const ACE_Service_Type *svc_rec = 0;        if (ACE_Service_Repository::instance()->find(name, &svc_rec) == -1)  return 0;        const ACE_Service_Type_Impl* type = svc_rec->type();        if (type == 0return 0;        ACE_Service_Object* obj = ACE_static_cast(ACE_Service_Object*, type->object());        return ACE_dynamic_cast(DLL_SERVICE_TYPE*, obj);     }} ;

            调用的主程序就非常简单:

        ACE_Service_Config::open( " Utility " );        ITimerListener  *  service  =  DynamicService < ITimerListener > ::Instance( " Test_Dynamic_Service " );    service -> OnTimer( 4 0 );

            ACE的Service Configurator Framework的功能很强大,支持plugin service的动态load、unload等。


    最新回复(0)