首先使用Home Brew安裝Protobuf:
brew install protobuf
安裝好之后,查看是否安裝成功
protoc --version
如果成功會有如下類似的版本號顯示:
libprotoc 3.1.0
這表明我安裝成功,并且版本號是3.1.0。
接著安裝protobuf的golang插件
go get -u -v github.com/golang/protobuf/proto
go get -u -v github.com/golang/protobuf/protoc-gen-go
因為protoc需要依賴調用protoc-gen-go,所以,它的路徑必須要添加到環境變量里面去。
它存在于
$GOPATH/bin之下。
我使用的shell是zsh,因此需要修改配置`/.zshrc
在最后添加配置:
export GOPATH=$HOME/Documents/golang/
export GOBIN=$GOPATH/bin
export PATH="$GOBIN:$PATH"
保存,然后重開zsh,即可。
我的workspace看起來是這樣的文件夾結構:
protobuf協議源文件放在了protocol/proto下面
helloworld.proto
syntax = "proto2";
package test;
message helloworld
{
required int32 id = 1; // ID
required string str = 2; // str
optional int32 opt = 3; //optional field
}
在這里需要注意幾點:
1.如果不定義package,編譯器會自行的將文件名生成package名,如上面的例子將會生成一一個package helloword;
2.因為golang遵循的是駝峰規則,message和field的名字首字母將會自動轉為大寫字母(如果首字母為下劃線,則下劃線會被自動轉換為大寫的X),而package名則不會;
接著我們就可以用命令行編譯出go代碼了:
protoc --go_out=. helloworld.proto
運行該命令之后,如果協議沒有語法錯誤,則會在proto文件同級目錄下生成一個hellword.pb.go的代碼文件,接著我們就能直接拿來用了。
如果是一個proto文件,使用一條命令生成是沒有問題的,但是在現實中,并不會只有一個,會有多個,那么就需要有批量的生成工具了,在mac/linux下面使用shell腳本可以搞定,在Windows下可以用bat批處理腳本搞定,下面給一個mac下的shell腳本示例代碼:
generate_code.sh
path=$(dirname $0)
path=${path/\./$(pwd)}
#echo $path
# /////////////////////////////////////////////////////////////////////////////
#
# 編譯Protobuf協議
#
# /////////////////////////////////////////////////////////////////////////////
protoc --version
protoc --go_out=$path/../ -I=$path $path/helloworld.proto
記得修改文件可執行權限,我就很偷懶,用:chmod 777 generate_code.sh搞定。
最后寫go的測試代碼了:
testpb.go
package main
import (
"./protocol"
"fmt"
"github.com/golang/protobuf/proto"
"log"
)
func main() {
// 創建一個消息
data_encode := &test.Helloworld{
Id: proto.Int32(11),
Str: proto.String("hello world!"),
Opt: proto.Int32(17),
}
// 進行編碼
data, err := proto.Marshal(data_encode)
if err != nil {
log.Fatal("marshaling error: ", err)
}
// 進行解碼
data_decode := &test.Helloworld{}
err = proto.Unmarshal(data, data_decode)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
// 測試結果
if data_encode.GetId() != data_decode.GetId() {
log.Fatalf("data mismatch %q != %q", data_encode.GetId(), data_decode.GetId())
}
fmt.Println("ID:", data_decode.GetId())
fmt.Println("Str:", data_decode.GetStr())
fmt.Println("Opt:", data_decode.GetOpt())
}
這里需要注意的是,import里面所填寫的是go文件的路徑,而無需要填寫文件名,也就是go文件的搜索路徑,默認的根目錄是
$GOPATH/src,如果是放在src里面,則直接寫"protocol"即可,但是我不希望如此,我把它放在了測試go文件的同級目錄下了,那么,我就需要這樣寫"./protocol"(需要注意的是,斜杠只能寫/而不能\)。
好了,現在開始編譯:
go build testpb.go
接著是執行:
./testpb
預期的結果是這樣的:
下面是測試代碼的完整打包:
/Files/tx7do/test_pb_go.zip
參考資料:https://github.com/golang/protobuf
http://www.jianshu.com/p/091be5025f03
https://my.oschina.net/ifraincoat/blog/510971
http://studygolang.com/articles/5213
http://www.cnblogs.com/baiyuxiong/p/4310121.html