thrift c_glib 库序列化学习

thrift c_glib 库序列化学习

最近在项目中需要在不同的语言(c, c++, java, python) 之间传递消息, 模式是 server(C++)需要向订阅者(observer) 发送更新.
大致的思路是server侦听某个端口, 然后observer 连接, 然后双方保持连接, 当有更新时, server 将消息下发给observer.
由于需要跨语言,所以我们需要一个序列化的库, 项目中之前引入的thrift 正好可以解决, 在需要支持的各种语言中, c语言由于本身没有面向对象, 所以特别单独学习了下thrift c_glib 的使用, 特此记录.

thrift c_glib

  1. thrift 是一个跨语言的RPC库, 自身带了很不错的网络框架,使用起来很简单, 基本上只需要很短的代码量就可以实现一个基于socket/HTTP的模式, 但是这个模式需要client端主动发起请求,然后server应答, 和我们的设计不太一致, 所以这里我只是把thrift 作为一个序列化的库来使用
  2. thrift 支持很多语言, 比如C++, Java, Python 等等, 但是它对C语言的支持需要glib 库, 并不是原生支持, 所以需要熟悉下glib库的用法

thrift c_glib 序列化例子

在安装好thrift 后, 我们需要编写消息体, 保存为 test.thrift
  1. struct test {
      1:boolean b1,
      2:i32 i2,
      3:string s3
    }

可以注意到这里的格式,非常类似c, 然后执行命令

  thrift -r --gen c_glib test.thrift

就会在gen-c_glib文件夹中生成对应的代码文件test_types.h, test_types.c
test_types.h 中定义了一些我们会用到的宏, 以及两个主要的结构体

  1. struct _test
    {
    ThriftStruct parent;
    /* public */
    gint32 i1;
    gboolean __isset_i1;
    gchar * s2;
    gboolean __isset_s2;
    };
    typedef struct _test test;
    struct _testClass
    {
    ThriftStructClass parent;
    };
    typedef struct _testClass testClass;
    GType test_get_type (void);
    #define TYPE_TEST (test_get_type())
    #define TEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TEST, test))
    #define TEST_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), _TYPE_TEST, testClass))
    #define IS_TEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TEST))
    #define IS_TEST_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TYPE_TEST))
    #define TEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TEST, testClass))
编写序列化过程
  1. #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(int num, const char* mesg)
    {
      test* t = g_object_new(TYPE_TEST, NULL);
      t->i1 = num;
      t->s2 = strdup(mesg);
      return t;
    }
    guchar* test2String(test* t, int* size) {
      ThriftTransport * transport = THRIFT_TRANSPORT(g_object_new(THRIFT_TYPE_MEMORY_BUFFER, "buf_size", 1024, 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(1024);
      *size = thrift_memory_buffer_read(THRIFT_TRANSPORT(transport), buf, 1024, NULL);
      g_object_unref(transport);
      g_object_unref(protocol);
      return buf;
    }
    test* string2Test(const guchar* buf, int size) {
      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);
      return t;
    }
    int main() {
      test * t = createTest(1024, "hello");
      int size;
      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;
    }

通过这样, 剩下的就只是server通过socket将转换成guchar的字符串 发送给客户端, 客户端在进行反序列化就可以得到信息了

时间: 2024-07-30 13:51:27

thrift c_glib 库序列化学习的相关文章

标准模板库(STL)学习探究之vector容器

标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据.为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>构造函数. Vectors 包含着一系列连续存储的元素,其行为和数组类

gdal库的学习和使用

1.windows下的编译 1.1.解压后打开nmake.opt,设置GDAL_HOME 1.2.进入vs的command promot,进入正常的那个即可,64位的没试过,可以参考gdal官网 1.3.nmake /f makefile.vc 1.4.nmake /f makefile.vc install 1.5.nmake /f makefile.vc devinstall 2.打开文件 #include "gdal_priv.h" #include "cpl_conv

C++的开源跨平台日志库glog学习研究(一)

作为C++领域中为数不多的好用.高效的.跨平台的日志工具,Google的开源日志库glog也算是凤毛麟角了.glog 是一个C++实现的应用级日志记录框架,提供了C++风格的流操作. 恰巧趁着五一我也学习研究了这个glog库,写个总结如下.走过路过的的各位牛人.高手可以忽略这篇文章了. 从code.google.com下载源码(在这里),在Visual Studio 2010中打开工程,如下: 可见只有四个工程,其中libglog和libglog_static分别是Windows下的动态库和静态

C++的开源跨平台日志库glog学习研究(二)--宏的使用

上一篇从整个工程上简单分析了glog,请看C++的开源跨平台日志库glog学习研究(一),这一篇对glog的实现代码入手,比如在其源码中以宏的使用最为广泛,接下来就先对各种宏的使用做一简单分析. 1. 日志输出宏 这里我们以一条最简单的日至输出为例说明: LOG(WARNING) << "This is a warning message"; 这里LOG是一个宏,其定义如下(logging.h line 487): #define LOG(severity) COMPACT

开源的人工神经网络计算库 FANN 学习笔记 1

开源的人工神经网络计算库 FANN 学习笔记 1 这年头机器学习非常的火,神经网络算是机器学习算法中的比较重要的一种.这段时间我也花了些功夫,学了点皮毛,顺便做点学习笔记. 介绍人工神经网络的基本理论的教科书很多.我正在看的是蒋宗礼教授写的<人工神经网络导论>,之所以选这本书,主要是这本比较薄,太厚的书实在是啃不动.这本书写的也比较浅显,用来入门正合适. 看书的同时也在网上找了找人工神经网络的库代码.感觉 FANN 这个库还不错,就顺道学了学这个库的使用方法. FANN 是个开源的 C 语言实

C++的开源跨平台日志库glog学习研究(三)--杂项

在前面对glog分别做了两次学习,请看C++的开源跨平台日志库glog学习研究(一).C++的开源跨平台日志库glog学习研究(二)--宏的使用,这篇再做个扫尾工作,算是基本完成了. 编译期断言 动态断言在调试过程中是一个很重要的手段,而且我们使用的也比较多.相应的,静态断言,也即是编译期断言随着模板编程.元编程的发展,也表现出了动态断言所没有的优势:在编译期完成断言检查,而不是等到运行时! 比如在glog的源码中,有如下代码(logging.h line 908): 1 template <b

《Linux多线程服务端编程——使用muduo C++网络库》学习笔记

第一章 线程安全的对象生命期管理 第二章 线程同步精要 第三章 多线程服务器的适用场合与常用编程模型 第四章 C++多线程系统编程精要 1.(P84)11个常用的最基本Pthreads函数: 2个:线程的创建和等待结束(join).封装为muduo::Thread 4个:mutex的创建.销毁.加锁.解锁.封装为muduo::MutexLock 5个:条件变量的创建.销毁.等待.通知.广播.muduo::Condition 2.(P85)不推荐使用读写锁的原因是它往往造成提高性能的错觉(允许多个

BOOST 库中filesyatem 库的学习

/*FileSyatem 库的学习 ------------------------------------------------------------------------------------------------------------库的使用方式 嵌入源码的形式: #define BOOST_SYSTEN_NO_LIB #define BOOST_FILESYSTEM_NO_LIB #include<boost\filesystem.hpp> ----------------

Robot framework--内置库xml学习(一)

Robot framework--内置库xml学习(一) 学习XML内置库,我认为需要掌握以下几个知识点: 第一:内置库的概念?有哪些内置库,大概都有什么关键字?有区分版本吗?跟RF版本有关么?为什么内置库有些需要import,有些不需要import? 第二:XML内置库使用的是python的哪个标准库?对这个标准库需要有哪些基本的了解? 第三:内置库是怎么构建起来的?基本关键字是否能灵活的使用? 第四:有时候可能需要稍微修改下内置库,比如增加一些关键字等,该怎么修改? 1.内置库的概念 内置库