window下使用protobuf

注:此处介绍的是在window vs2012环境下c++使用云风protobuf

云风protobuf文章:
Proto Buffers in Lua:http://blog.codingnow.com/2010/08/proto_buffers_in_lua.html
继续完善protobuf库:http://blog.codingnow.com/2010/08/protobuf_for_lua.html
Protocol Buffers for C:http://blog.codingnow.com/2011/12/protocol_buffers_for_c.html

云风protobuf下载:https://github.com/cloudwu/pbc


step1:
下载云风的protobuf
     ---打开pbc-master下的vs工程pbc.sln
     ---生成pbc项目,在pbc-master\Debug下会生成一个pbc.lib的库
     ---拷贝pbc-master\Debug\pbc.lib , pbc-master\pbc.h 放到一个新建的目录里(如pbclib)


step2:
创建protobuf结构文件,此处例子为一个简单的登录协议login.proto

//客户端向服务端请求可登陆的角色信息
message C2s_login_info {
     required string list_id = 1;//玩家账号
}

//角色信息结构
message LoginUserList {
     required string uid = 1;     //角色ID
     required string name = 2;     //角色名称
     required int32 photo = 3;     //角色头像
}

//服务端向客户端发送可登陆的角色信息
message S2c_login_info {
     required string list_id = 1;     //玩家账号
     repeated LoginUserList list = 2;     //可登陆的角色列表
}


创建好用通过protobuf库官方工具生成的.pb数据块(login.pb)
具体操作:
1.进入http://code.google.com/p/protobuf/downloads/list 下载protoc-2.5.0-win32.zip
2.解压获得执行文件protoc.exe
3.将login.proto放到protoc.exe目录下
4.在protoc.exe下执行指令:protoc.exe --descriptor_set_out=./login.pb ./login.proto ,即可生成login.pb文件


step3:pbc.h几个常用接口说明
@1:注册协议文件
struct pbc_env * env = pbc_new();
struct pbc_slice slice;
read_file("login.pb", &slice);
int ret = pbc_register(env, &slice);
assert(ret == 0);


@2:写入数据
struct pbc_wmessage* w_msg = pbc_wmessage_new(env, "S2c_login_info");
//账号
pbc_wmessage_string(w_msg, "list_id", "12345", 0);
//角色数据1
struct pbc_wmessage * user = pbc_wmessage_message(w_msg , "list");
pbc_wmessage_string(user , "uid", "111" , 0);
pbc_wmessage_string(user , "name", "aaa" , 0);
pbc_wmessage_integer(user , "photo", 12345 , 0);
//角色数据2
user = pbc_wmessage_message(w_msg , "list");
pbc_wmessage_string(user , "uid", "222" , 0);
pbc_wmessage_string(user , "name", "bbb" , 0);
pbc_wmessage_integer(user , "photo", 54321 , 0);
//将数据写入缓存区
struct pbc_slice sl;
pbc_wmessage_buffer(w_msg, &sl);
pbc_wmessage_delete(w_msg);


@3:读数据
struct pbc_rmessage* r_msg = NULL;
r_msg = pbc_rmessage_new(env, "S2c_login_info", &sl);
//读取账号ID
string list_id = pbc_rmessage_string(r_msg, "list_id", 0 , NULL);
//读取角色数据
int user_n = pbc_rmessage_size(r_msg, "list");
for (int i=0;i      struct pbc_rmessage * p = pbc_rmessage_message(r_msg , "list", i);
     string uid = pbc_rmessage_string(p , "uid", i ,NULL);
     string name = pbc_rmessage_string(p, "name", i, NULL);
     int photo = pbc_rmessage_integer(p, "photo", i, NULL);
     printf("uid:%s, name:%s, photo:%d \n", &uid, &name, photo);
}
pbc_rmessage_delete(r_msg);


我们用 pbc_rmessage_size 可以查询 message 中某个 field 被重复了多少次。如果消息中并没有编码入
这个 field ,它能返回 0 感知到。

integer 不区分 32bit 数和 64bit 数。当你能肯定你需要的整数可以用 32bit 描述时,pbc_rmessage_integer
的最后一个参数可以传 NULL ,忽略高于 32bit 的数据。

需要注意的是,如果使用 pbc_wmessage_integer 压入一个负数,一定要将高位传 -1 。因为接口一律把传入
参数当成是无符号的整数。在正式开发中,我是决不允许传入负数的

wmessage 的用法更像是不断的向一个未关闭的消息包类压数据。当你把整个消息的内容都填完后,可以
用 pbc_wmessage_buffer 返回一个 slice 。这个 slice 里包含了 buffer 的指针和长度。


step4:例子实现
1.新建vs项目Win32控制台应用程序gametest
2.把pbc.h,pbc.lib,login.pb文件拷贝到工程里

window下使用protobuf_第1张图片

3.把pbc.lib和pbc.h导入你的工程里
     ---项目->属性->连接器->常规->附加库目录->导入你的pbc.lib

window下使用protobuf_第2张图片

// gametest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include
#include
#include
#include "pbc.h"
#pragma comment(lib, "pbc.lib")
 
using namespace std;
 
struct pbc_env * env = pbc_new();
 
static void read_file (const char *filename , struct pbc_slice *slice) {
     FILE* f;
     fopen_s(&f, filename, "rb");
     if (f == NULL) {
          slice->buffer = NULL;
          slice->len = 0;
          return;
     }
     fseek(f,0,SEEK_END);
     slice->len = ftell(f);
     fseek(f,0,SEEK_SET);
     slice->buffer = malloc(slice->len);
     fread(slice->buffer, 1 , slice->len , f);
     fclose(f);
}
 
static void test(struct pbc_env *env) {
     struct pbc_wmessage* w_msg = pbc_wmessage_new(env, "S2c_login_info");
 
     //账号
     pbc_wmessage_string(w_msg, "list_id", "12345", 0);
     //角色数据1
     struct pbc_wmessage * user = pbc_wmessage_message(w_msg , "list");
     pbc_wmessage_string(user , "uid", "111" , -1);
     pbc_wmessage_string(user , "name", "aaa" , -1);
     pbc_wmessage_integer(user , "photo", 12345 , 0);
     //角色数据2
     user = pbc_wmessage_message(w_msg , "list");
     pbc_wmessage_string(user , "uid", "222" , -1);
     pbc_wmessage_string(user , "name", "bbb" , -1);
     pbc_wmessage_integer(user , "photo", 54321 , 0);
 
     struct pbc_slice sl;
     char buffer[1024];
     sl.buffer = buffer, sl.len = 1024;
     pbc_wmessage_buffer(w_msg, &sl);
 
     struct pbc_rmessage* r_msg = NULL;
     r_msg = pbc_rmessage_new(env, "S2c_login_info", &sl);
     //读取账号ID
     string list_id = pbc_rmessage_string(r_msg, "list_id", 0 , NULL);
     printf("list_id:%s \n", &list_id);
     //读取角色数据
     int user_n = pbc_rmessage_size(r_msg, "list");
     for (int i=0;i           struct pbc_rmessage * p = pbc_rmessage_message(r_msg , "list", i);
          string uid = pbc_rmessage_string(p , "uid", i ,NULL);
          string name = pbc_rmessage_string(p, "name", i, NULL);
          int photo = pbc_rmessage_integer(p, "photo", i, NULL);
          printf("uid:%s, name:%s, photo:%d \n", &uid, &name, photo);
     }
 
     pbc_rmessage_delete(r_msg);
     pbc_wmessage_delete(w_msg);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
     struct pbc_slice slice;
     read_file("login.pb", &slice);
     int ret = pbc_register(env, &slice);
     assert(ret == 0);
     test(env);
     return 0;
}

window下使用protobuf_第3张图片

原文:https://blog.csdn.net/yeungxuguang/article/details/18452341 

 

参考:https://blog.csdn.net/viewsky11/article/details/78144620

你可能感兴趣的:(protobuf)