go的go protobuf 使用这个问题是不是一个bug

运行protoc 把.proto文件生成.pb.go文件,遇到的问题以及解决方案
Expected &required&, &optional&, or &repeated&.
参考链接http://blog.csdn.net/sparkexpert/article/details/
执行protoc &version时,发现版本是2.4.1,但是解决原博客那么复杂
问题一解决方案:直接下载高版本的protoc.exe文件即可
[libprotobuf WARNING google/protobuf/compiler/parser.cc:547] No syntax specified for the proto file: ticket.proto. Please use 'syntax = &proto2&;' or 'syntax = &proto3&;' to specify a syntax version. (Defaulted to proto2 syntax.)
参考链接/network-dev/protobuf-proto3-vs-proto2.html讲述了proto2和proto3的差别
问题二解决方案:只需要在.proto文件开头加上syntax = &proto3&;或者syntax = &proto2&;即可1082人阅读
S1: C/C++(719)
S1: C++ STL(64)
s2: 软件Develop进阶(825)
s2: 实战Network编程(133)
s2: 活捉Bug(220)
& & & & 我们已经介绍过protobuf的使用了, 故不再赘述, 下面我们来看看如下代码的一个小bug:
& & & & test.proto内容为:
package NS;
message PointReq
required int32 x=1;
required int32 y=2;
}& & & &main.cpp为:
#include &iostream&
#include &string&
#include &test.pb.h&
using namespace NS;
int main()
point.set_x(1);
point.set_y(0);
bool ret = point.SerializeToString(&tmp); // 这里要传地址
printf(&encode ok!\n&);
printf(&encode error!\n&);
return -1;
// 为了便于网络传输, 这里需要转化成指针式buffer
const char *p = tmp.c_str();
string s =
PointReq point2;
ret = point2.ParseFromString(s);
printf(&decode ok, %d, %d\n&, point2.x(), point2.y());
printf(&decode error!\n&);
return -2;
& & & & 结果为:
taoge@localhost Desktop& make clean
rm -fr *.o main
taoge@localhost Desktop& make
-L/usr/local/lib
-lprotobuf
-o main.o main.cpp
-L/usr/local/lib
-lprotobuf
-o test.pb.o test.pb.cc
g++: -lprotobuf: linker input file unused because linking not done
g++: -lprotobuf: linker input file unused because linking not done
-L/usr/local/lib
-lprotobuf
-o main main.o test.pb.o
taoge@localhost Desktop& ./main
encode ok!
decode error!
taoge@localhost Desktop& & & & &为什么是失败呢? &请自己思考一下, 如果没有结果, 可以参考我之前的博文:http://blog.csdn.net/stpeace/article/details/
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3515493次
积分:48493
积分:48493
排名:第65名
原创:1732篇
转载:142篇
评论:1875条
(18)(74)(61)(14)(32)(52)(8)(10)(28)(56)(32)(26)(15)(42)(63)(38)(39)(75)(43)(4)(20)(33)(17)(11)(7)(48)(53)(51)(52)(35)(20)(53)(41)(35)(13)(32)(36)(7)(1)(47)(23)(26)(4)(13)(4)(19)(72)(13)(2)(14)(45)(32)(7)(3)(28)(53)(106)(68)注意required是必须要求的字段, optional是可选字段. 同时注意, id=1, 后面的数字仅仅是一个unique标志而已, 保证唯一性就OK!
然后使用protoc test.proto --go_out=. 编译这个文件, 生成的文件名称为test.pb.go文件! 如果这个路径下有多个文件需要编译,
那么执行protoc --go_out=. *.proto就可以. 注意--go_out=后面的参数是生成的文件的路径, 本文生成的文件在'.'当前路径下.
生成的代码如下:
// Code generated by protoc-gen-go.
// source: 1.proto
// DO NOT EDIT!
Package test is a generated protocol buffer package.
It is generated from these files:
It has these top-level messages:
package test
import proto "/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type MyMsg struct {
`protobuf:"varint,1,req,name=id" json:"id,omitempty" bson:"id,omitempty"`
*string `protobuf:"bytes,2,req,name=str" json:"str,omitempty" bson:"str,omitempty"`
`protobuf:"varint,3,opt,name=opt" json:"opt,omitempty" bson:"opt,omitempty"`
XXX_unrecognized []byte
`json:"-"`
func (m *MyMsg) Reset()
{ *m = MyMsg{} }
func (m *MyMsg) String() string { pactTextString(m) }
func (*MyMsg) ProtoMessage()
func (m *MyMsg) GetId() int32 {
if m != nil && m.Id != nil {
return *m.Id
func (m *MyMsg) GetStr() string {
if m != nil && m.Str != nil {
return *m.Str
func (m *MyMsg) GetOpt() int32 {
if m != nil && m.Opt != nil {
return *m.Opt
func init() {
特别注意: 生成的文件中的package是test, 那么文件必须放在test文件夹下! 否则会报错:
&can't load package: package test: found packages test (test.pb.go) and main (main.go)&
下面写一个测试程序:
// main.go
package main
t "./test"
"/golang/protobuf/proto"
func main(){
// 创建一个对象, 并填充字段, 可以使用proto中的类型函数来处理例如Int32(XXX)
hw := t.MyMsg{
Id: proto.Int32(1),
Str: proto.String("iyviasbjasdv"),
Opt: proto.Int32(2),
// 对数据进行编码, 注意参数是message指针
mData, err := proto.Marshal(&hw)
if err != nil {
fmt.Println("Error1: ", err)
// 下面进行解码, 注意参数
var umData t.MyMsg
err = proto.Unmarshal(mData, &umData)
if err != nil {
fmt.Println("Error2: ", err)
// 输出结果
fmt.Println(*umData.Id, "
", *umData.Str, "
", *umData.Opt)
简单的用法完毕, 然后我们就能愉快地使用protobuf定义自己的消息协议了, 赞!
只有protobuf中的编解码原理, 有时间再去深究了~~~}

我要回帖

更多关于 go protobuf 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信