注:此处介绍的是在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
我们用 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文件拷贝到工程里
文章图片
3.把pbc.lib和pbc.h导入你的工程里 ---项目->属性->连接器->常规->附加库目录->导入你的pbc.lib
文章图片
// 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
文章图片
安装文件及gametest例子下载:http://download.csdn.net/detail/yeungxuguang/6861775
【window下使用protobuf】
推荐阅读
- quick|quick-coco2d-xV3.2 win32下集成风云pcb解析protobuf
- 移动开发|cocos2dx之Label实现换行
- cocos2dx|cocos2dx使用节点Node对象的作用,特性和使用的时机
- cocos2dx|关于UIText换行