C++反序列化--一种基于class infomation反射库的反序列化数据结构

2022/8/22 14:24:37

本文主要是介绍C++反序列化--一种基于class infomation反射库的反序列化数据结构,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

序列化与反序列化概念:

将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯。这个将程序数据转化成能被存储并传输的格式的过程被称为“序列化”(Serialization),而它的还原过程则可被称为“反序列化”(De-serialization).

详见: C++与序列化 CSDN博客_c++ 序列化

反射:

维基百科的定义:反射是指计算机程序在运行时可以访问、检测和修改它本身状态或行为的一种能力。 有点抽象,实际上反射就是程序在运行时动态获取对象信息以及调用对象方法的能力。可以对比java的运行期反射机制,C++没有自带的反射机制,需要依赖外部库来实现。

ProtoBuff

Boost.Serialization

Boost.Serialization可以创建或重建程序中的等效结构,并保存为二进制数据、文本数据、XML或者有用户自定义的其他文件。该库具有以下吸引人的特性

Serialization - Tutorial (boost.org)

MFC Serialization

Windows平台下可使用MFC中的序列化方法。MFC对CObject 类中的序列化提供内置支持。

.Net Framework

.NET的运行时环境用来支持用户定义类型的流化的机制。它在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

QJSON

www.json.org

由于Bytestream指令流中可以包含各种依赖嵌入式底层结构的数据格式以及排布方式,我们可以提供自定义的Bytestream数据格式与配套的序列化/反序列化引擎,包括存储数据格式的C++数据结构以及writer()/reader()/parser()等一系列API。

 

 

Codec指令流驱动序列化/反序列化引擎:

 

 

 

 Bytestream数据格式的Header包含ABIcode,反映了C++类对象的原始内存排布信息,以及classhash来映射对应的reflection容器,寻找对应的class反射文件。

常规的JSON文件格式,考虑一种包含多种基础数据类型的数据结构:

C++直接操作python的dict模块需要使用pybind11操作库,实际工程实践中可能会需要交叉编译,我们直接定义一种数据结构通过模拟并操作dict数据结构,配合反射库的生成文件来解析并读取Bytestream中的C++ class info,参考N叉树:

 1 class cpp_dict{
 2 public:
 3 std::unordered_mapstd::string,std::stringMap0;//basic converted type
 4 std::unordered_mapstd::string,std::uint64_tMap1;//basic converted type
 5 vectorstd::uint32_thash;
 6 std::unordered_setstd::uint32_tenum_values;
 7 vector<cpp_dict*>Node;
 8 std::uint32_t count;
 9 bool flag;
public:
11 cpp_dict(){
12    this->Node.resize(1,nullptr);
13    this->hash.resize(4,0);
14    this->flag=true;
15  }
16 }

基础API包括插入操作,包括成员变量独立插入,自底向上构造插入(insert_test_1b1()),BFS插入与DFS插入(按照指定的Node track);待实现API为删除和匹配操作:

 1 class cpp_dict{
 2 public:
 3 std::unordered_map<std::string,std::string>Map0;//basic converted type
 4 std::unordered_map<std::string,std::uint64_t>Map1;//basic converted type
 5 vector<std::uint32_t>hash;
 6 std::unordered_set<std::uint32_t>enum_values;
 7 vector<cpp_dict*>Node;
 8 std::uint32_t count;
 9 bool flag;
10 public:
11 cpp_dict(){
12     this->Node.resize(1,nullptr);
13     this->hash.resize(4,0);
14     this->flag=true;
15 }
16 
17 void insert_str(string key,string str)
18 {
19     this->Map0[key]=str;
20 }
21 void insert_int(string key,std::uint64_t x)
22 {
23     this->Map1[key]=x;
24 }
25 void insert_hash(vector<std::uint32_t>& vec)
26 {
27     for(int i=0;i<vec.size();i++)
28     {
29         this->hash[i]=vec[i];
30     }
31 }
32 void insert_set(vector<std::uint32_t>& set_vec)
33 {
34     for(auto x:set_vec)
35     {
36         this->enum_values.insert(x);
37     }
38 }
39 void insert_test_1b1(cpp_dict* tar)//add cpp_dict* one by one
40 {
41     if(!this->Node[0]){
42         this->Node[0]=tar;
43     }else{
44         this->Node.push_back(tar);
45     }
46     return;
47 }
48 void insert_cpp_dict_BFS(vector<cpp_dict*>& temp)//add cpp_dict* to current Node
49 {
50     int idx=0;
51     if(!this->Node[0]){
52         this->Node.pop_back();
53     }
54     for(int i=0;i<temp.size();i++){
55         this->Node.push_back(temp[i]);
56         cout<<"*insert success!*"<<endl;
57     }
58     return;
59 }
60 void insert_cpp_dict_DFS(cpp_dict* cur, cpp_dict* Temp, vector<int>& track)//add cpp_dict* Temp to next Node, track index 
61 {
62     for(int i=0;i<track.size();i++){
63         if(cur->Node.size()==0){
64             cur->Node.push_back(Temp);
65             return;
66         }else{
67             if((!cur->Node[track[i]] && i<track.size()-1) || (track[i]>= cur->Node.size())){
68                 cout<<"*insert error!*"<<endl;
69                 return;
70             }else{
71                 cout<<track[i]<<"# ";
72                 if(i==track.size()-1){
73                     cur->Node[track[i]]=Temp;
74                     cout<<"*insert success!*"<<endl;
75                     return;
76                 }
77                 cur=cur->Node[track[i]];
78             }
79         }
80     }
81     return;
82 }
83 void erase();
84 void find();
85 };

测试函数包含成员变量打印,以及节点深度测试:

 1 void print_info(string blank, cpp_dict* cur)
 2 {
 3     for(auto p:cur->Map0){
 4         cout<<blank<<p.first<<":"<<p.second<<endl;
 5     }
 6     for(auto p:cur->Map1){
 7         cout<<blank<<p.first<<":"<<p.second<<endl;
 8     }
 9     cout<<blank<<"hash:["<<endl;
10     int k=0;
11     for(auto x:cur->hash){
12         k++;
13         if(k==cur->hash.size()){
14             cout<<blank<<" "<<x<<endl;
15             break;
16         }
17         cout<<blank<<" "<<x<<","<<endl;
18     }
19     cout<<blank<<"]"<<endl;
20     k=0;
21     cout<<blank<<"enum_values:{";
22     for(auto x:cur->enum_values){
23         k++;
24         if(k==cur->enum_values.size()){
25             cout<<blank<<x;
26             break;
27         }
28         cout<<blank<<" "<<x<<",";
29     }
30     cout<<"}"<<endl;
31     cout<<blank<<"count:"<<cur->count<<endl;
32     cout<<blank<<"flag:"<<cur->flag<<endl;
33     cout<<blank<<"members:["<<endl;
34     return;
35 }
36 void search(cpp_dict* cur,int dep,string blank)//DFS search
37 {
38     if(!cur || cur->Node.size()==0){
39         cout<<blank<<"/current depth:"<<dep<<"/ "<<endl;
40         return;
41     }else{
42         print_info(blank,cur);
43         for(auto x:cur->Node){
44             search(x,dep+1,blank+"  ");
45         }
46         cout<<blank<<"]"<<endl;
47     }
48     return;
49 }

测试主函数(实现了三层节点嵌套):

 1 int main() {
 2     cpp_dict* root=new cpp_dict();
 3     cpp_dict* temp=new cpp_dict();
 4     cpp_dict* base=root;
 5 
 6     temp->insert_str("name", "temp");
 7     temp->insert_int("offset", 0);
 8     temp->insert_int("test_node", 0);
 9     vector<std::uint32_t>vec={1,1,1,1};
10     vector<std::uint32_t>set_vec={0};
11     root->insert_hash(vec);
12     root->insert_set(set_vec);
13     //search(temp,0,"");
14     root->insert_str("name", "root");
15     root->insert_int("offset", 1);
16 
17     vector<cpp_dict*>Temp;
18     Temp.push_back(temp);
19     cpp_dict* temp1=new cpp_dict();
20     temp1->insert_str("name", "temp1");
21     temp1->insert_int("test_node", 1);
22     temp1->insert_int("offset", 0);
23     temp1->insert_int("test_node", 0);
24     Temp.push_back(temp1);
25 
26     //root=root->Node[0];
27     //root->insert_test_1b1(temp1);
28     //insert_test(root,Temp);
29 
30     //root->insert_cpp_dict_BFS(Temp);
31     
32     cpp_dict* temp2=new cpp_dict();
33     temp2->insert_str("name", "temp2");
34     temp1->insert_test_1b1(temp2);
35     temp->insert_test_1b1(temp1);
36     root->insert_test_1b1(temp);
37 
38     vector<int>track={0,0,0};
39     //root->insert_cpp_dict_DFS(root,temp2,track);
40     //root->insert_test(root,Temp);
41     cout<<"{"<<endl;
42     search(base,0,"");
43     cout<<"}"<<endl;
44     return 0;
45 }

打印:

{
name:root
offset:1
hash:[
 1,
 1,
 1,
 1
]
enum_values:{0}
count:0
flag:1
members:[
  name:temp
  test_node:0
  offset:0
  hash:[
   0,
   0,
   0,
   0
  ]
  enum_values:{}
  count:0
  flag:1
  members:[
    name:temp1
    offset:0
    test_node:0
    hash:[
     0,
     0,
     0,
     0
    ]
    enum_values:{}
    count:0
    flag:1
    members:[
      name:temp2
      hash:[
       0,
       0,
       0,
       0
      ]
      enum_values:{}
      count:0
      flag:1
      members:[
        /current depth:4/ 
      ]
    ]
  ]
]
}

结果符合预期,注意深度是4,考虑到了最底层的空节点。

 



这篇关于C++反序列化--一种基于class infomation反射库的反序列化数据结构的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程