采集器C++代码在Red Hat各版本操作系统移植出现得问题

       由于公司项目的需要,需要将采集器c++代码在Red hat不同版本操作系统移植,出现了好多问题,所以写此文来做一次全面的总结。

     首先现介绍一些采集器的功能:
  •  响应Server服务器的请求;
  • 维护访问物理设备的信息;
  • 使用snmp协议周期地访问物理设备,获取需要地数据;
  • 存入数据库。
    采集器运行的环境:
  • 编程语言  C++
  • 操作系统   RHAS2.1 ,RH9.0,RHAS4.4
  • 编译器       gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)  gcc version 3.4.6 20060404 (Red Hat 3.4.6-3) ,gcc version 2.96 20000731 (Red Hat Linux 7.2 2.96-108.1)
     采集器使用的第三方开发包:
  • log4cpp-0.3.5rc3         : log日志开发包
  • net-snmp-5.2.1            : snmp开发包
  • unixODBC-2.2.11        : sqlserver2k访问sql接口
  • freetds-0.64-stable      : sqlserver2k访问sql接口
  • ACE                              : 跨操作系统C++开发平台 
  • snmp++                        : snmp开发包
  • expat                             : expat 是解析xml配置文件的api
      在不同操作系统移植时,出现问题最多的是第三方开发包的移植,  例如 :
     在平台 RHAS2.1 下,只能使用 ACE5.4.1 log4cpp-0.3.5rc3zdsmodi.tar 开发包,否则编译不成功;
     在平台 RH9.0 下,只能使用 ACE5.4.1 log4cpp-0.3.5rc3.tar.gz 开发包,否则编译不成功;
     在平台 RHAS4.4 下,可以使用 ACE5.5 log4cpp-0.3.5rc3.tar.gz 开发包;
    自己开发的代码由于按照 c ++标准开发的,基本上是重新编译即可。
现总结如下:
一、使用的日志开发包是通过修改得到的,由于早期是使用 RHAS2.1 操作系统,高版本的 log4cpp-0.3.5rc3 不支持,低版本也不支持。自己是从网上找到 dedian log4cpp 日志的 .cpp, .h 源文件,复制到  log4cpp-0.3.5rc3 目录下,居然编译通过,而且还能使用 api log 日志了。这真是幸运呀。以后运行平台都使用 RHAS4.4 RH9.0 ,可以使用高版本的 log4cpp-0.3.5rc3
二、使用 net-snmp-5.2.1  主要是用来在 linux 机上启动 snmpd 守候进程,采集器来读取 pc 机上的一些配置信息。
      red hat 9 平台下 net-snmp 在编译会出问题: /usr/bin/ld: cannot find -lelf 那么需要装两个 rpm bzip2-devel-1.0.2-8.i386.rpm elfutils-devel-0.76-3.i386.rpm ,重新编译即可。
     Red hat as4,4 平台下, 编译会出错,报 /usr/lib/libpopt.so: could not read symbols: File in wrong format
将各个 Makefile 文件中对应的 popt 去掉,重新编译就可以通过。
三、 sqlserver2k 访问 sql 接口包 unixODBC-2.2.11 freetds-0.64-stable  ,是用来在 linux 平台访问 windows 平台下的 sqlserver2k 数据的开发包,在移植操作系统的时候,出现使用开发包自带的 tsql isql 命令访问数据库能够正常访问,带使用程序使用对应的 api 老是报登陆不正确的错误提示,原因是用户名,密码编码的问题,要使用以下语句才可以:
       char *charset = NULL;
      setlocale(LC_ALL, "");
      char* locale = setlocale(LC_ALL, NULL);
  
      DBSETLCHARSET(mLogin,"ISO-8859-1" );
      DBSETLNATLANG(mLogin, "us_english");
       还有一个隐患,就是高版本的 sqlserver 数据库有可能不在支持 tds 协议访问数据库,以后的可能会有问题
四、 SNMP++ 是我最熟悉的 snmp 协议的 api ,不过是第一次在 linux 使用,有些代码比如 snmpget 等操作还不能编译通过,还有 makefile 也写的不好,需要重新整理,主要是没有时间。
五、在移植时不同的编译器在编译也会出问题,在编译器 gcc3.2.2 ,主要是使用 var-args.h 的函数如 var_start,var_end ,而 RHAS4.4 使用的是 gcc3.4.6, 其使用的是 c ++标准的函数库 std-args.h ,不在支持 var-args.h 的函数,所以需要移植,移植代码仅仅举如下例子说明就明白了。这主要是代码没有严格按照 标准的 c ++来编写而造成的问题。
        RHAS2.1 RH9 0 使用的 gcc3.2.2 ,其代码是:
#include
int getAllElemText(XmlFile,NodeName,va_alist)
char *XmlFile ;
char *NodeName ;
va_dcl

 
    char *pNodeName ; 
    va_list ap;
     int j; 
 
    va_start(ap);
    for(j=0;;j++)
    {
      pNodeName = va_arg(ap,char *);
      if(!pNodeName)
         break;
     
      #ifdef DEBUG
      printf("NO:[%d]pNodeName=[%s] /n",j,pNodeName);
      #endif  
   }
   va_end(ap); 
 
   return 0;
}
RHAS4.4 gcc3.4.6 只支持 std-arg.h, 所以其对应的代码如下:
#include
int getAllElemText(char* XmlFile,char* NodeName, ...)
{
    char *pNodeName ; 
     va_list ap;
     int j; 
  
    va_start(ap,NodeName);
    for(j=0;;j++)
    {
        pNodeName = va_arg(ap,char *);
        if(!pNodeName)
             break;
         #ifdef DEBUG
             printf("NO:[%d]pNodeName=[%s] /n",j,pNodeName);
         #endif      
               
     }
     va_end(ap);
    
     return 0;
}       
gcc3.2  中,下面代码是能编译通过,并且能正常运行
unsigned int pos = mPacketStr.find_first_of(":");
 if(pos == string::npos)
 {
  CFileLog::Instance()->log(getpid(),"CAPPResponse","parse","response has not : char",CFileLog::INFO);
  return 1;
 }
但是在 gcc3.4.6 中,虽然能够编译通过,但是出警告错误:
     warning: comparison is always true due to limited range of data type
要把上面的代码改成这样才可以:
   string::size_type pos = mPacketStr.find_first_of(":");
   if(pos == string::npos)
  {
    CFileLog::Instance()->log(getpid(),"CAPPResponse","parse","response has  not :   char",CFileLog::INFO);
    return 1;
 }
五、 ACE 使用出的问题最多。
       RHAS2.1 平台下,高版本的 ace 不能在其上编译,最高只支持 ace5.4.1 版本的,惨呀,但是花了好长时间试图编译成功,实在不行了,在网上满地的找原因,才在一个 ace 商用支持的网站发现 RHAS2.1 最高只支持 ace5.4.1 版本的,我那个郁闷呀。
        RH9.0 平台下,高版本的 ace5.5 不能在其上编译 , 只能使用 ace5.4.1 版本的
       而在 RHAS4.4 平台下, ace5.4.1 居然又编译不过了,这次我学乖了,首先在网上看发现, RHAS4.4 平台下最低只能支持 ace5.4.7 的,原来的又废了,一横心下了最高版本的 ace5.5 ,在 ace 目录下
   %mkdir build
   %cd build
   %make
   %cp /home/creco/ats/ACE_wrappers/build/ace/.libs/* /home/creco/ats/ACE_wrappers/lib
      我没有使用 make install 进行安装只是将库文件拷贝到一个我程序能够找的目录,谁想我的代码老是报 ace 的错误,找了好长时间才发现问题,发现是在 ace 目录下没有找到对应的 config.h 文件,可以在编译的目录下 build/ace 拷贝到 ACE_ROOT/ace 目录下即可。    
 
 

你可能感兴趣的:(程序人生)