注:此处介绍的是在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
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文件拷贝到工程里
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
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;
}
原文:https://blog.csdn.net/yeungxuguang/article/details/18452341
参考:https://blog.csdn.net/viewsky11/article/details/78144620