ACE 是一个很大的东西,每个人学习路径可能都不一样。我的方法首先阅读 C++ Network Programming, Volume 1 ,让自己明了ACE 的设计思路;再从实际的小项目入手,逐步的用 ACE 内容替换掉自己的东西,在比较和实践之间求得较深的了解。
     就一个正常项目而言,一个配置文件是必不可少的,那就先从这里入手了。linux/unix 程序可能经常用到命令行方式,不过我还是比较喜欢 windowsini 格式的,当然,有xml 的更好,不过 ACE 里暂时没有提供。配置文件的使用很简单,ACE 提供的类也很友好。在这里主要是整理一些细节,让大家不在这里浪费太多时间。
 

  

 1、ACE 配置类简介与使用
 
   先给出一个印象(为了直指主题,所有错误处理都被清除,具体例子请看最后源码): 

ACE入门 (二)配置文件 (改)    ACE_Configuration_Heap config; 
        config.open();
ACE入门 (二)配置文件 (改)     ACE_Registry_ImpExp impExp(config);    
// win32的注册表导出格式
ACE入门 (二)配置文件 (改)     
//ACE_Ini_ImpExp impExp(config);          // windows的.ini格式,注意读出来的都是字符串,类型需要自己转换
ACE入门 (二)配置文件 (改)
     impExp.import_config(ACE_TEXT("配置文件名"));    // 读取配置文件 
ACE入门 (二)配置文件 (改)
 
ACE入门 (二)配置文件 (改)     ACE_Configuration_Section_Key section;
// 指向一个配置节section
ACE入门 (二)配置文件 (改)
     config.open_section(config.root_section(), ACE_TEXT("节名"), 0, section);
ACE入门 (二)配置文件 (改) 
ACE入门 (二)配置文件 (改)     
// 读取字符串
ACE入门 (二)配置文件 (改)
     ACE_TString str;   
ACE入门 (二)配置文件 (改)     config.get_string_value(section, ACE_TEXT(
"键名"), str); // ACE_Ini_ImpExp,只能使用这一种方法
ACE入门 (二)配置文件 (改) 
ACE入门 (二)配置文件 (改)    
// 读取整型
ACE入门 (二)配置文件 (改)
     u_int i;
ACE入门 (二)配置文件 (改)     config.get_integer_value(section, ACE_TEXT(
"键名"), i);
ACE入门 (二)配置文件 (改) 
ACE入门 (二)配置文件 (改)    
// 读取二进制
ACE入门 (二)配置文件 (改)
     void * data_out = 0// 最好使用智能指针
ACE入门 (二)配置文件 (改)
     size_t length = 0;
ACE入门 (二)配置文件 (改)     config.get_binary_value(section, ACE_TEXT(
"键名"), data_out, length);
ACE入门 (二)配置文件 (改)     delete []data_out;

    可以浏览一下 ACE_Configuration_Heap 和 ACE_Ini_ImpExp 或 ACE_Registry_ImpExp 之间的关系。不需要套上术语来理解,简化一下代码对此很有帮助
 
 一个超简化的ACE_Configuration_Heap

1ACE入门 (二)配置文件 (改) class ACE_Export ACE_Configuration_Heap : public ACE_Configuration
2;

 值得注意的是 ACE_Registry_ImpExp 和 ACE_Ini_ImpExp ,这两个类都继承自 ACE_Config_ImpExp_Base,分别处理不同的格式。
 
 简化版本的 ACE_Config_ImpExp_Base, 具体实现请看 Configuration_Import_Export.h

1ACE入门 (二)配置文件 (改) class ACE_Config_ImpExp_Base
2;


 从两个简化的类,可以想象 ACE_Registry_ImpExp 和 ACE_Ini_ImpExp对import_config的具体实现会将不同格式的文件里的配置数据转化成相同的格式化的数据,并将之放到 ACE_Configuration_Heap 的 SECTION_MAP *index_。 ACE_Config_ImpExp_Base 具体实现的作用就是作为一个适配器。

2、ACE 配置格式说明:


 (内容来自Configuration_Import_Export.h的注释)

   2.1. ACE_Registry_ImpExp 

   使用win32 注册表文件导出文件格式,格式如下:


ACE入门 (二)配置文件 (改)  [Section]
ACE入门 (二)配置文件 (改)          
"key"="String Data"
ACE入门 (二)配置文件 (改)          
"key"=dword: 十六进制数值
ACE入门 (二)配置文件 (改)          
"key"=hex: 二进制
ACE入门 (二)配置文件 (改)          注意,二进制的写法如下 
ACE入门 (二)配置文件 (改)          
"pwd"=hex:31,32,33,34,35,36,37,38


 2.2. ACE_Ini_ImpExp

 从文件中导入字符串配置数据。充许 not-typed 值(没有 #,dword: hex:, 等前缀),在标准的.ini和.conf中跳过空白字符(tabs和spaces)。 值 (在等式的右边)可以被双引号限定,使得tabs或spaces能够留在字符串中。调用者必须自己转换字符串到类型。格式如下:

ACE入门 (二)配置文件 (改) TimeToLive     =    100
ACE入门 (二)配置文件 (改) Delay          
=    false
ACE入门 (二)配置文件 (改) Flags          
=    FF34  # 可以象这样写注释
ACE入门 (二)配置文件 (改) Heading        
=    "ACE - Adaptive Communication Environment"

  
 3、一个友好的函数

     使用此类配置文件时,如果用到会变化的配置集合,我们经常遇到这样的写法


ACE入门 (二)配置文件 (改) [section]
ACE入门 (二)配置文件 (改) 
"size"=dword:2
ACE入门 (二)配置文件 (改) 
"item_1"="value1"
ACE入门 (二)配置文件 (改) 
"item_2"="value2"


     这样写因为 window 提供的 API 只能一项一项读取,我们只能在读取了size 的值后,才能拼凑出"item_1"键名来取到相应的值。在实际操作中维护人员很容易遗漏操作,增加了选项但忘记增加size的值。ACE则提供了非常友好的enumerate_values函数,配合一下 boostsplit 使用起来感觉很好。
 
     一个非常简单的TCP转发程序的配置文件,将一端口接收到的数据转发至指定地址的端口,可以开多个服务端口:

ACE入门 (二)配置文件 (改) [server\listen_items]
ACE入门 (二)配置文件 (改) ;listen_port, target_ip, target_port, timeout (second), validate
ACE入门 (二)配置文件 (改) 
"item_1"="19998,192.168.168.217,8101,60,1"
ACE入门 (二)配置文件 (改) 
"item_2"="8000, 192.168.0.57, 23, 60, 1"

        实际的代码摘录,但不一定能编译呵 :-)  

 1ACE入门 (二)配置文件 (改) 
 2ACE入门 (二)配置文件 (改) #include <boost/algorithm/string.hpp>
 3ACE入门 (二)配置文件 (改) #include <boost/lexical_cast.hpp>
 4ACE入门 (二)配置文件 (改) using namespace boost;
 5ACE入门 (二)配置文件 (改)
 6ACE入门 (二)配置文件 (改) 
 7ACE入门 (二)配置文件 (改) class ListenItem
 8

 

  这样就可以不写

1ACE入门 (二)配置文件 (改)stringstream s;
2ACE入门 (二)配置文件 (改) s << "item_" << i+1;
3ACE入门 (二)配置文件 (改)

     这样的代码了,也避免了维护人员遗漏操作

     4、编译选项 
     
    上面代码有用到 boost 的相关内容,如果你使用的是 ACE Programmer's Guide 的 2.5 How to Build Your Applications 节所介绍的Makefile,在 linux 下面的话是不可少的
    
     CPPFLAGS = -i"$(BOOST_ROOT)" 
     
   当然,还要在.bash_profile或相应原地方加入类似说明:
      
     BOOST_ROOT=$HOME/boost_X_XX_X
     export BOOST_ROOT

   //WuErPing 补充  (2006/12/28 )
    5、Use Unicode Character Set/Use Multi-Byte Character Set      
      上面的代码是使用Use Multi-Byte Character Set选项编译的,相应的编译ACE时也没有用到#define ACE_USES_WCHAR 1,如果使用Use Unicode Character Set是有问题的。要使写好的代码能同时在两个编译项中切换,除了利用ACE宏定义的ACE_TEXT,ACE_TString来处理字符串,用到的C++标准库string与stringstream时也需要做些处理。

#endif



    

 

 

 

 

 

 

 

            

 

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
  • 2021-12-21
  • 2022-12-23
  • 2022-01-29
  • 2021-11-23
  • 2021-09-23
猜你喜欢
  • 2021-11-07
  • 2021-05-07
  • 2021-08-17
  • 2021-12-08
  • 2021-06-29
  • 2022-12-23
  • 2021-09-04
相关资源
相似解决方案