c++ rtti-plus-0.0.4 for gcc-4.5.1,可以使用通用的 Save Load函数(四) print_type_name.cpp

[ 2012-03-31 21:13:03 | 作者: Admin ]
: | |
#include <stdio.h>
#include <typeinfo>
#include <string.h>
#define PRINTF(format, args...){\
printf("%s (%d),%s: "format" \n", __FILE__ ,__LINE__,__FUNCTION__, ## args);\
}

class AAA{
public:
  virtual void test(){
    PRINTF("");
  }
  long long lolo;
};
struct CCC:public AAA{
  int hh;
};
class BBB:public AAA{
public:
  virtual void test(){
    PRINTF("");
  }
  long long lolo;
  char ch;
  signed char sch;
  wchar_t wch;
  signed short ssh;
  unsigned short ush;
  signed int sin;
  unsigned int uin;
  signed long slo;
  unsigned long ulo;
  float fo;
  double dou;
  AAA*aaa;
  char*pch;
  char ach[6];
};
void PrintTypeName(const std::type_info *tinfo,char *object){
  const char *member_cls_name=tinfo->name();
  char member_type=member_cls_name[0];//取出一个字节
  PRINTF("class name is %s",member_cls_name);
  switch(member_type){
    case 'b'://bool
      printf("bool \n");
      break;
    case 'c'://char
      printf("char\n");
      break;
    case 'a'://signed char
      printf("signed char\n");
      break;
    case 'w'://wchar_t
      printf("wchar_t\n");
      break;
    case 's'://signed short
      printf("signed short\n");
      break;
    case 't'://unsigned short
      printf("unsigned short\n");
      break;
    case 'i'://signed int
      printf("signed int\n");
      break;
    case 'j'://unsigned int
      printf("unsigned int\n");
      break;
    case 'l'://signed long
      printf("signed long\n");
      break;
    case 'm'://unsigned long
      printf("unsigned long\n");
      break;
    case 'f'://float
      printf("float\n");
      break;
    case 'd'://double
      printf("double\n");
      break;
    case 'P':
      printf("point\n");
      break;
    case 'A':
      printf("array\n");
      break;
    case '0'://名称串长度
    case '1':
    case '2':
    case '3'://3多继承的类
    case '4':
    case '5':
    case '6'://6单一的类
    case '7':
    case '8':
    case '9':
      printf("%c\n",member_type);
      break;
/*    case '_':
      printf("_\n");
      break;
*/
//        case 'Pd'://double*
//          printf("double *");
//          break;
//        case 'A_d'://double[]
//          printf("double []");
//          break;
    default:
      printf("other\n");
      break;      
//        case OBJECT_POINT_TYPE:{
//          Save(member_info.type_id,*((char**)((char*)this+member_info.offset)));
//          relation(this,property,member_info);
//        }
//        case OBJECT_TYPE:{//member is class_type
//          Save(member_info.type_id,((char*)this+member_info.offset));
//          relation(this,property,member_info);
//        }
//      }
//    }
  }
}
//mangle.c::write_builtin_type()
enum COMPLATE_TYPE{
  NOT_COMPLATE_TYPE,
  COMPLATE_TYPE,
  UNSURE,
  UNKNOWN,
};
int is_complete_type(char ch1,char ch2){
  int result=NOT_COMPLATE_TYPE;
  switch(ch1){
    case 'a'://signed char
    case 'b'://bool
    case 'c'://char
    case 'd'://double
    case 'e'://long double, __float80
    case 'f'://float
    case 'g'://__float128
    case 'h'://unsigned char
    case 'i'://signed int
    case 'j'://unsigned int
    case 'l'://signed long
    case 'm'://unsigned long
    case 'n'://__int128
    case 'o'://unsigned __int128
    case 'r'://long double
    case 's'://signed short
    case 't'://unsigned short
    case 'w'://wchar_t
    case 'x'://long long , int64
    case 'u'://<source-name> # vendor extended type, __uint512 __int256
      break;
    case 'D':
      switch(ch2){
        case 's'://char16_t
        case 'i'://char32_t
        case 'f'://dfloat32
        case 'd'://dfloat64
        case 'e'://dfloat128
          break;
        case 'F'://FIXED_POINT_TYPE
          result=UNSURE;
          break;
      }
      break;
    case 'P'://Indicates a pointer type. Followed by the type pointed to.
    case 'A'://Indicates a C++ array type.
      result=UNSURE;
      break;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      result=COMPLATE_TYPE;
      break;
//    case 'Pd'://double*
//      printf("double *");
//      break;
//    case 'A_d'://double[]
//      printf("double []");
//      break;
    case '_':
//    case 'e'://Indicates extra unknown arguments ....
//    case 't'://Indicates a template instantiation.
    case 'v'://void

    case 'C'://A modifier to indicate a const type.
        //Also used to indicate a const member function
        //(in which cases it precedes the encoding of the method's class).
    case 'F'://Used to indicate a function type.
    case 'H'://Used to indicate a template function.
    case 'J'://Indicates a complex type.
    case 'Q'://Used to mangle qualified names, which arise from nested classes.
        //Should also be used for namespaces (?).
        //In Java used to mangle package-qualified names, and inner classes.
    case 'R'://Indicates a reference type. Followed by the referenced type.
    case 'S'://A modifier that indicates that the following integer type is signed. Only used with char.
        //Also used as a modifier to indicate a static member function.
    case 'T'://A back reference to a previously seen type.
    case 'U'://A modifier that indicates that the following integer type is unsigned.
        //Also used to indicate that the following class or namespace name is encoded using Unicode-mangling.
    case 'V'://A modified for a const type or method.
    case 'X'://Encodes a template type parameter, when part of a function type.
    case 'Y'://Encodes a template constant parameter, when part of a function type.
    case 'Z'://Used for template type parameters.
      //The letters `G', `M', `O', and `p' also seem to be used for obscure purposes ...
/*    case 'Sa':    case 'Ss':    case 'Sb':    case 'Si':    case 'So':
    case 'Sd':    case 'St':    case 'Ut':    case 'Ui':    case 'cv':
    case 'C1':    case 'C2':    case 'D0':    case 'D1':    case 'D2':
    case 'Dv':    case 'Dp':    case 'Dt':    case 'DT':    case 'N':
    case 'V':    case 'K':    case 'M':    case '_Z':*/
    default:
      result=UNKNOWN;
      printf("error --------------unknown type=%c",ch1);
      break;      
  }
  return result;
}
int is_complete_type(const std::type_info *tinfo){
  bool result=false;
  const char *member_cls_name=tinfo->name();
  PRINTF("class name is %s",member_cls_name);
  int type=UNKNOWN;
  int i=0;
  do{
    type=is_complete_type(member_cls_name[i],member_cls_name[i+1]);//取出2个字节
    if(type==NOT_COMPLATE_TYPE||type==COMPLATE_TYPE)
      return type;
    i++;
  }while(type==UNSURE);
  
  return type;
}
#define SPACE_COUNT 2
void PrintInfo(const std::type_info *tinfo,char *object){
  static int space=0;
  space+=SPACE_COUNT;
  char space_string[space+1];
  memset(space_string,' ',space);
  space_string[space]=0;

  PRINTF("%stype_name=%s",space_string,tinfo->name());
  PrintTypeName(tinfo,object);
  int n=tinfo->get_member_count();
  PRINTF("%smember_count=%d",space_string,n);

  const std::type_info *cinfo=tinfo->get_type_info();
  if(cinfo!=0){
    PRINTF("%scomplete_type_info=0x%x",space_string,cinfo);
    if(is_complete_type(tinfo)){
      PrintInfo(cinfo,object);
    }
  }else{
    PRINTF("%scomplete_type_info=0",space_string);
  }
  if(n==0){
    space-=SPACE_COUNT;
    return ;
  }
  const std::member_info *minfo=tinfo->get_member_info();
  PRINTF("%smember_info_start=0x%x\n",space_string,minfo);
  for(int i=0;i<n;i++){
    PRINTF("%smember_name=%s",space_string,minfo->__name);
    PRINTF("%smember_offser=%d",space_string,minfo->__offset);
    PRINTF("%smember_type_info=0x%x",space_string,minfo->__type);
    PrintInfo(minfo->__type,object+minfo->__offset);
    minfo++;
  }
  space-=SPACE_COUNT;
  //printf("type_name=%s",tinfo->name());
}
int main(){
  BBB b;
  AAA *a=&b;
//  int member_count=typeid(b).get_member_count();
//  printf("member_count=%d\n",member_count);
  a->test();
  PrintInfo(&typeid(*a),(char*)(a));
  return 0;
}
[最后修改由 Admin, 于 2013-04-13 13:52:24]
评论Feed 评论Feed: http://www.vTalkback.com/blog/feed.asp?q=comment&id=206

浏览模式: 显示全部 | 评论: 1 | 引用: 0 | 排序 | 浏览: 4276
引用 Admin
[ 2012-04-04 20:25:00 ]
可以从基类遍历子类的成员变量,然后根据成员变量的类型(长度)、名称、偏移量等信息进行相应的处理

发表
表情图标
[smile] [confused] [cool] [cry]
[eek] [angry] [wink] [sweat]
[lol] [stun] [razz] [redface]
[rolleyes] [sad] [yes] [no]
[heart] [star] [music] [idea]
UBB代码
转换链接
表情图标
悄悄话
用户名:   密码:  
验证码 * 请输入验证码