Thrift C_glib Library Serialization Learning
Recently in the project you need to pass messages between different languages (C, C + +, Java, Python), and the schema is that server (c + +) needs to send updates to Subscribers (Observer).
The general idea is that the server listens on a port, then observer the connection, and then both sides remain connected, and when there is an update, the server sends the message to observer.
Because of the need for cross-language, so we need a serialized library, the project before the introduction of the thrift can be solved, in the various languages that need to support, C language because itself is not object-oriented, so special alone to learn the use of the next thrift C_glib, hereby recorded.
Thrift C_glib
- Thrift is a cross-language RPC library, itself with a very good network framework, it is very simple to use, basically only a short amount of code can implement a socket/http-based mode, but this mode requires the client side to initiate the request, and then the server answer, It's not exactly the same as our design, so here I'm just using thrift as a serialized library.
- Thrift supports many languages, such as C + +, Java, Python, etc., but its support for C requires glib libraries, not native support, so you need to familiarize yourself with the usage of the glib library.
Thrift C_glib Serialization Example after installing the thrift, we need to write the message body, save as Test.thrift
struct Test { 1: Boolean B1, 2: i32 i2, 3:string S3}
You can notice the format here, very similar to C, and then execute the command
thrift -r --gen c_glib test.thrift
The corresponding code file is generated in the Gen-c_glib folder Test_types.h, TEST_TYPES.C
Test_types.h defines some of the macros we will use, as well as two main structures
struct_test{thriftstruct parent;/* Public*/gint32 I1;gboolean __isset_i1;gchar*S2;gboolean __isset_s2;}; typedefstruct_test test;struct_testclass{thriftstructclass parent;}; typedefstruct_testclass TestClass; GType Test_get_type (void);#defineType_test (Test_get_type ())#defineTest (obj) (G_type_check_instance_cast ((obj), type_test, TEST))#defineTest_class (c) (G_type_check_class_cast ((c), _type_test, TestClass))#defineIs_test (obj) (G_type_check_instance_type ((obj), type_test))#defineIs_test_class (c) (G_type_check_class_type ((c), type_test))#defineTest_get_class (obj) (G_type_instance_get_class ((obj), type_test, TestClass))
Writing the serialization process
#include <string.h>#include<stdio.h>#include<glib-Object.h>#include<thrift/c_glib/protocol/thrift_binary_protocol.h>#include<thrift/c_glib/transport/thrift_memory_buffer.h>#include"Gen-c_glib/test_types.h"Test* Createtest (intNumConst Char*MESG) {Test* t =g_object_new (Type_test, NULL); T->I1 =num; T->S2 =StrDup (MESG);returnT;} Guchar* Test2string (test* t,int*size) {Thrifttransport* Transport = Thrift_transport (G_object_new (Thrift_type_memory_buffer,"buf_size",1024x768, NULL)); Thriftprotocol* protocol = Thrift_protocol (G_object_new (Thrift_type_binary_protocol,"Transport", Transport, NULL)); Thrift_struct_write (Thrift_struct (t), Protocol, NULL); Guchar* buf = (guchar*) g_malloc0 (1024x768);*size = Thrift_memory_buffer_read (Thrift_transport (TRANSPORT), buf,1024x768, NULL); G_object_unref (transport); G_object_unref (protocol);returnbuf;} Test* String2test (Constguchar* buf,intsize) {Thrifttransport* Transport = Thrift_transport (G_object_new (Thrift_type_memory_buffer,"buf_size", size, NULL)); Thriftprotocol* protocol = Thrift_protocol (G_object_new (Thrift_type_binary_protocol,"Transport", Transport, NULL)); Thrift_memory_buffer_write (transport, (Gpointer) buf, size, NULL); Test* t =g_object_new (Type_test, NULL); Thrift_struct_read (Thrift_struct (t), Protocol, NULL); G_object_unref (transport); G_object_unref (protocol);returnt;}intMain () {test* t = createtest (1024x768,"Hello");intsize; Guchar* buf = test2string (t, &size); G_object_unref (t); Test* NT =string2test (buf, size); G_free (BUF); printf ("%d%s\n", Nt->i1, nt->S2); G_object_unref (NT);return 0;}
By doing this, the only thing left is for the server to send the string to the client through the socket, and the client can get the information by deserializing the Guchar.
Thrift C_glib Library Serialization Learning