解決proto3的"Timestamp" is not defined問題

pamxy發表於2015-10-22
因為protobuf3新增了Timestamp型別,所以想試一下,但結果出現如下錯誤,搜了一下google,結果沒多少個有答案的,只好自己解決;

圖1

找到message Timestamp的定義是在\protobuf-3.0.0-beta-1\src\google\protobuf下的timestamp.proto檔案裡,直接將此檔案複製到我使用它的那個DataAccessSerivceMassages.proto檔案的同一目錄,然後當然不行的,之後實在不能,就直接將timestamp.proto檔案的Timestamp型別的定義直接複製進DataAccessSerivceMassages.proto檔案裡,結果居然可以;那麼讓這個定義再放在一個新的檔案裡然後import此檔案呢,結果也是可以;然後對比一下新建的此檔案和原本的timestamp.proto檔案,發現,新的檔案沒有package google.protobuf;這一行定義,然後終於明白,原來是作用域的問題;
解決的方法為:
1.在用proto檔案生成程式碼的bat語句中加入Timestamp.proto的路徑,我的是在原始碼中D:\WorkCode\protobuf-3.0.0-beta-1\src\google\protobuf的位置,因為在import是有加上google/protobuf的目錄位置,所以只匯入D:\WorkCode\protobuf-3.0.0-beta-1\src目錄就可以了;你可能會奇怪,為什麼可以使用兩個"-I"引數,是的,在https://developers.google.com/protocol-buffers/docs/proto中的

The Protocol Compiler is invoked as follows:

protoc –proto_path=IMPORT_PATH –cpp_out=DST_DIR –java_out=DST_DIR –python_out=DST_DIR path/to/file.proto
IMPORT_PATH specifies a directory in which to look for .proto files when resolving importdirectives. If omitted, the current directory is used. Multiple import directories can be specified by passing the –proto_path option multiple times; they will be searched in order. -I=IMPORT_PATH can be used as a short form of –proto_path.

請翻翻觀看…

人家就說明,如果要匯入多個目錄,可以使用多次”–proto_path=”來匯入多個目錄,當然”-I=”與”–proto_path=”是等價的。

%PROTOBUF_HOME%\Release\protoc -I=. -I=D:/WorkCode/protobuf-3.0.0-beta-1/src –grpc_out=./generate –plugin=protoc-gen-grpc=%GRPC_HOME_RELEASE%\grpc_cpp_plugin.exe ./DataAccessSerivceInterface.proto

%PROTOBUF_HOME%\Release\protoc -I=. -I=D:/WorkCode/protobuf-3.0.0-beta-1/src –cpp_out=./generate ./DataAccessSerivceInterface.proto

(注:之後才發現,不需要新增這個目錄也可以,因為timestamp.proto生成的timestamp.pb.cc檔案已經在編譯libprotobuf.lib檔案時作為原始碼編譯進去了,而編譯protoc.exe裡也用到了libprotobuf.lib,所以自然預設已經有原始碼了,所以不用再匯入!)

2.開啟你的.proto檔案,在裡面新增,記得別忘了";" 分號,不然會出錯;

import public “google/protobuf/timestamp.proto”;
**(注意:timestamp.proto的t必定是小寫的,不然如果寫錯成大寫會有如下問題:
Error 2 error C3861: ‘protobuf_AddDesc_google_2fprotobuf_2fTimestamp_2eproto’: identifier not found f:\workspace\qt\pamxysql\sql\dataaccessservice\src\proto\generate\dataaccessserivcemassages.pb.cc 2033
Error 1 error C2039: ‘protobuf_AddDesc_google_2fprotobuf_2fTimestamp_2eproto’ : is not a member of ‘google::protobuf’ f:\workspace\qt\pamxysql\sql\dataaccessservice\src\proto\generate\dataaccessserivcemassages.pb.cc 2033
)**)

3.在你需要用到Timestamp型別的message裡使用google.protobuf.Timestamp而不是Timestamp,往往我們匯入了正確的目錄但仍提示說Timestamp未定義就是因為此定義,因為作用域不同,一般我們會定義自己的package,而Timestamp的package是google.protobuf,兩個作用域不一樣,導致你定義的型別找不到Timestamp,而現在我們直接指名是在google.protobuf裡的Timestamp,所以終於能夠編譯成功了!

message ReqAddFriend
{
uint64 personID=1;
uint64 friendID=2;
google.protobuf.Timestamp addDateTime=3;
string comment=4;
}

圖2

相關文章