标签:
最近在项目中需要在不同的语言(c, c++, java, python) 之间传递消息, 模式是 server(C++)需要向订阅者(observer) 发送更新.
大致的思路是server侦听某个端口, 然后observer 连接, 然后双方保持连接, 当有更新时, server 将消息下发给observer.
由于需要跨语言,所以我们需要一个序列化的库, 项目中之前引入的thrift 正好可以解决, 在需要支持的各种语言中, c语言由于本身没有面向对象, 所以特别单独学习了下thrift c_glib 的使用, 特此记录.
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 中定义了一些我们会用到的宏, 以及两个主要的结构体
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))
#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的字符串 发送给客户端, 客户端在进行反序列化就可以得到信息了
标签:
原文地址:http://www.cnblogs.com/gtsfreer/p/5112827.html