Serialize and deserialize C++ objects using the acl library

       When developing network applications, data communication between modules is commonplace. In order to meet the requirements of data exchange during these data communications, programmers have invented various data formats: using binary data structures (early C programmers), using XML, using SOAP (a tricky design), using URL encoding, using JSON format, etc. When using these data formats for data exchange when the client interacts with the server, it is bound to go through the tedious process of data encoding and data decoding. The early binary data structure format is relatively simple for C programmers. It is OK to directly align the structure when decoding, but it is very troublesome for other languages ​​(such as JAVA, PHP). JAVA language not only needs to use bytes The streams are aligned one by one, and the data packing and filling method of the C structure must be considered; the SOAP method seems to meet the purpose of data exchange in various programming languages, but data bloat is a big problem. In order to transmit several Bytes of data would have to encapsulate a lot of XML markup. In order to free the programmers of cross-language development from the troublesome data encoding and decoding, many serialization/deserialization tool libraries came out later, such as Facebook's thrift and Google's protobuf. These tool libraries are very powerful, but one problem is that the pre-defined schemas required by these tool libraries are not friendly enough to the people, adding a lot of extra learning costs.

      Recently , a C++ object serialization and deserialization library has been added to the acl library by [email protected] , which greatly improves the programmer's programming efficiency and code accuracy. The acl serialization library implements the conversion function between C++ struct objects and JSON objects, and the usage is very simple.

 

      1. Features of the acl serialization library :

      1. You can directly convert C++ struct objects to Json objects, and you can also deserialize Json objects into C++ struct objects;

      2. Support C++ struct object including constructor and destructor;

      3. Members in a C++ struct object support common basic types (short, int, long, long long, char*) and standard C++ class objects;

      4. Members in C++ struct objects support pointer types;

      5. The members in the C++ struct object support common C++ container types: std::vector, std::list, std::map, and support the inner nesting of container objects;

      6. When the members in the C++ struct object are basic data types (such as: short, int, long, long long) and pointer types, it is supported to initialize these members directly in the struct (C++11);

      7. Support adding comments (// or /**/) in C++ struct;

      8. Support multiple inheritance of C++ struct objects;

      9. Support multi-level inclusion in C++ struct objects, it is recommended to use inclusion instead of inheritance;

      10. Support C++ struct members to add comment items: //Gson@optional indicates that the member variable is optional, //Gson@required indicates that the member is required, and the default is required.

 

      2. Limitations of using the acl serialization library :

      1. The member type in struct cannot be char type, mainly because there is no char type in the Json object;

      2. There must be no const constant qualifier before the members in the struct, mainly because these members need to be assigned values ​​during deserialization;

      3. C++ keywords are not supported in struct: public, private, protected;

      4. The member variable names in struct must not be: $json, $node, $obj, because these keywords are occupied by the code generated by the acl serialization library;

      5. The definition of the struct type with the inclusion relationship must be in the same file;

      6. The array function of pure C language is not supported. For example, for int a[10], serialization and deserialization cannot be performed because the actual storage quantity in the array a cannot be known exactly, so it is recommended to use std::vector<int > replace it.

 

      3. The process of using the acl serialization library :

      1. First compile the acl library: run before the acl directory: make build_one , it will generate three basic libraries of acl (lib_acl/lib/lib_acl.a, lib_protocol/lib/lib_protocol.a, lib_acl_cpp/liblib_acl_cpp.a), and also A collection of these three libraries (lib_acl.a and lib_acl.so) will be generated in the acl root directory;

      2. Compile the acl serialization tool: enter the app/gson directory, run make , and generate the gson tool, which will be used to generate serialized C++ code according to the user-defined struct;

      3. Define your own struct structure (you can define more than one) and save it in a file (the file suffix is ​​.stub );

      4. Use the gson tool to generate the C++ code required for serialization based on the user's .stub file: ./gson -d path , where path is the directory containing the .stub file, and three files , gson.cpp, gson. h and .h header files converted by .stub ;

      5. Include gson.h and the .h header file converted by the .stub file into your own code;

      6. For each user-defined struct, the gson.h header file will provide the serialization and deserialization methods of the struct object. Assuming that the user has customized a structure type: struct user, then the tool The gson.h file generated by gson contains the following five methods:

      1)、acl::string gson(const user &$obj);

               Convert the user object $obj filled by the user to a Json string;

      2)、acl::json_node& gson(acl::json &$json, const user &$obj);

               Convert the user object $obj filled by the user into an acl::json_node node object in the acl::json object $json and return it, so that the user can add the returned acl::json_node& object reference to the $json object middle;

      3)、acl::json_node& gson(acl::json &$json, const user *$obj);

               The function is the same as the method in 2), except that the $obj parameter is an object pointer;

      4)、std::pair<bool,std::string> gson(acl::json_node &$node, user &$obj);

               Convert an acl::json_node Json node object into a user-defined struct user object. If $node is the root node in the Json object, the root node can be obtained by $json.get_root(), and $obj stores the converted result;

      5)、std::pair<bool,std::string> gson(acl::json_node &$node, user *$obj);

               The function is the same as the method in 5), except that the $obj parameter is an object pointer.

 

      Fourth, for example:

      Suppose the custom struct object is as follows:

// struct.stub
#pragma once
#include <string>

struct user
{
        std::string name;
        std::string domain;
        int age;
        bool male;
};

      The process for the application to manipulate the user object is as follows:

// main.cpp
#include "stdafx.h"
#include <list>
#include <vector>
#include <map>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include "struct.h" // Converted from struct.stub by gson tool
#include "gson.h" // Generated by gson tool based on struct.stub

// serialization process
static void serialize(void)
{
	user u;

	u.name = "zsxxsz";
	u.domain = "263.net";
	u.age = 11;
	u.male = true;

	acl::json json;

	// Convert user object to json object
	acl::json_node& node = acl::gson(json, u);

	printf("serialize:\r\n");
	printf("json: %s\r\n", node.to_string().c_str());
	printf("\r\n");
}

// deserialization process
static void deserialize(void)
{
	const char *s = "{\"name\": \"zsxxsz\", \"domain\": \"263.net\", \"age\": 11, \"male\": true}";
	printf("deserialize:\r\n");

	acl::json json;
	json.update(s);
	user u;

	// Convert json object to user object
	std::pair<bool, std::string> ret = acl::gson(json.get_root(), u);

	// If the conversion fails, print the reason for the conversion failure
	if (ret.first == false)
		printf("error: %s\r\n", ret.second.c_str());
	else
		printf("name: %s, domain: %s, age: %d, male: %s\r\n",
			u.name.c_str(), u.domain.c_str(), u.age,
			u.male ? "yes" : "no");
}

int main(void)
{
	serialize();
	deserialize();
	return 0;
}

 

      5. Reference:

      acl github:https://github.com/acl-dev/acl

      acl osc:https://git.oschina.net/acl-dev/acl/tree/master

      More C++ serialization examples: https://github.com/zhengshuxin/acl/tree/master/app/gson/test

      Compilation and use of acl: http://zsxxsz.iteye.com/blog/1506554

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327013492&siteId=291194637