從零開始建構 Google Protocol Buffer / protobuf 的helloworld工程
- 從零開始建構 Protocol Buffer / protobuf 的helloworld工程
-
- 前言
- 1. 下載下傳protobuf
- 2. cmake生成protobuf工程
- 3. vs編譯protobuf工程
- 4. 編寫項目自己的.proto檔案
- 5. 将protobuf引入自己的工程
- 注意事項
從零開始建構 Protocol Buffer / protobuf 的helloworld工程
PS:若懶得看正文,文末提供了本文所述過程生成的VS工程的下載下傳連結,可直接下載下傳使用。
前言
-
本文環境:
Win10(Windows SDK version 10.0.17763.0) + VS2017 + protobuf-3.19.0
- 整體步驟:
- 下載下傳
源碼protobuf
- 運作
以生成cmake
protobuf的vs工程
- vs編譯protobuf工程(生成所需*.lib檔案和protoc.exe)
- 編寫項目自己的.proto檔案,并運作
生成對應的.h和.cc檔案protoc.exe
- 将protobuf引入自己的工程使用
- 下載下傳
1. 下載下傳protobuf
- 下載下傳protobuf
下載下傳位址: https://github.com/protocolbuffers/protobuf/releases
目前最新版本為3.19.0,在下載下傳頁面中直接下載下傳
protobuf-cpp-3.19.0.zip
注意:
若不想自己編譯,想下載下傳項目編譯好的release檔案時,在将protobuf引入自己的工程後,再編譯時會提示缺少檔案。
報錯資訊為:實際去fatal error C1083: 無法打開包括檔案: “google/protobuf/port_def.inc”: No such file or directory
的解壓目錄的
protoc-3.19.0-win64.zip
檔案夾下看,确實也不存在對應檔案。
include
壓縮包中的
protoc-3.19.0-win64.zip
檔案夾與
include
protobuf-cpp-3.19.0.zip
源碼相比,也确實少了一些檔案。
是以最終還是得下載下傳源碼自行編譯,在源碼的src目錄中有相關檔案。
- 下載下傳cmake
下載下傳位址 https://cmake.org/download/
目前最新版本為3.22.0,在下載下傳頁面中直接下載下傳
cmake-3.22.0-rc1-windows-x86_64.zip
protobuf-cpp-3.19.0.zip
需要使用cmake生成vs工程,是以需要下載下傳cmake工具。
若自己電腦上原來已經有cmake工具,可不下載下傳,用自己電腦上的cmake工具即可。
2. cmake生成protobuf工程
解壓
cmake-3.22.0-rc1-windows-x86_64.zip
後,運作
cmake-gui.exe
在彈出視窗中按如下步驟操作。(在下述例子中,protobuf解壓後的目錄為
E:/TestProj/protobuf-cpp-3.19.0
)
-
步驟1
在cmake-gui.exe的彈出界面中仿照下圖進行配置。(此處編譯平台選擇為
和VS2017
)x64
- 步驟2
在紅色背景框區域可更改預設生成配置,更改完成後點選
Configure
按鈕更新配置,随後點選
Generate
按鈕生成vs工程。
-
步驟3
等待vs工程生成成功後,即可點選
打開protobu的VS工程。Open Project
在最後一步可直接單擊
Open Project
按鈕,cmake可直接調用VS2017打開protobuf的VS解決方案工程檔案。
也可以自己去
目錄用
E:\TestProj\protobuf-cpp-3.19.0\build
打開
VS2017
檔案。
protobuf.sln
3. vs編譯protobuf工程
在打開的protobuf工程中分别編譯
libprotobuf
和
protoc
這兩個項目。(其他項目編譯與否,請看自己的實際情況)。正常情況下,僅編譯
libprotobuf
和
protoc
兩個項目已經可以滿足核心需要。
- 以debug為例,生成一下檔案:libprotobufd.lib、libprotocd.lib和protoc.exe
debug版本生成的檔案如下圖
- 以release為例,生成一下檔案:libprotobuf.lib、libprotoc.lib和protoc.exe
release版本生成的檔案如下圖
4. 編寫項目自己的.proto檔案
.proto
檔案的文法請檢視其它blog或者檢視官方指南 https://developers.google.com/protocol-buffers/docs/proto3
在本案例中以
proto3
為helloworld案例。
proto2
的案例請自行修改。
// helloworld.proto
syntax = 'proto3';
package hellopb;
message helloworld
{
int32 id = 1; // ID
string str = 2; // str
}
解釋:
定義了一個package 名字叫做 hellopb,對應C++的
定義了一個消息名稱為
namespace
的消息類型,該消息有2個成員,類型為 int32 的 id,另一個為類型為 string 的成員 str。
helloworld
使用
protoc.exe
對消息進行處理,生成C++編譯器可識别的
.h
和
.cc
檔案
生成指令如下:(在使用時要注意.exe和.proto檔案的路徑)。
protoc.exe -I=. --cpp_out=. ./helloworld.proto
不知道 proto.exe的參數含義時,可使用 protoc.exe --help
指令檢視幫助文檔。
可參照下圖:
5. 将protobuf引入自己的工程
此處以Debug版本為例
-
生成helloworld工程
使用vs2017自己生成一個helloworld測試工程。
-
拷貝依賴項
将生成的
檔案拷貝至項目的lib目錄。(注意:本文使用的是靜态庫,若需要動态庫,則需在cmake階段選擇生成dll動态庫)libprotobufd.lib、libprotocd.lib和protoc.exe
-
拷貝頭檔案
将源碼
下的E:\TestProj\protobuf-cpp-3.19.0\protobuf-3.19.0\src
檔案夾拷貝至helloworld項目的google
檔案夾include
文字說明:
- 在VS工程中,配置以下工程屬性:
: 添加
[配置屬性]->[C/C++]->[正常]->[附加包含目錄]
檔案夾所在路徑,預設在項目的include下
: 添加
[配置屬性]->[連接配接器]->[正常]->[附加庫目錄]
和
libprotobufd.lib
檔案所在路徑
libprotocd.lib
:添加
[配置屬性]->[連接配接器]->[輸入]->[附加依賴項]
和
libprotobufd.lib
libprotocd.lib
- 在代碼頁中配置:
直接在需要寫消息的cpp檔案中 #include “helloworld.pb.h”
也可按下述例圖進行配置。
項目檔案目錄
檔案拷貝後的目錄為:
解決方案
修改附加包含目錄
修改附加庫目錄
修改附加依賴項
// main.cpp
#include <iostream>
#include <fstream>
#include "msg/helloworld.pb.h" // 包含生成的頭檔案
int main(int argc, char* argv[])
{
// 消息封裝
hellopb::helloworld msgwrite;
msgwrite.set_id(1001);
msgwrite.set_str("hello world");
char buff[1024] = { 0 };
msgwrite.SerializeToArray(buff, 1024); // 序列化消息
//解析消息
hellopb::helloworld msgread;
msgread.ParseFromArray(buff, 1024);
std::cout << "id:" << msgread.id() << std::endl;
std::cout << "str:" << msgread.str() << std::endl;
}
運作後輸出為:
id:1001
str:hello world
注意事項
Q:若在添加依賴項和庫後進行編譯時報出錯誤
error LNK2038
1>------ 已啟動生成: 項目: ProtocolBuf, 配置: Debug x64 ------
1>libprotobufd.lib(arenastring.obj) : error LNK2038: 檢測到“RuntimeLibrary”的不比對項: 值“MTd_StaticDebug”不比對值“MDd_DynamicDebug”(main.obj 中)
1>libprotobufd.lib(message_lite.obj) : error LNK2038: 檢測到“RuntimeLibrary”的不比對項: 值“MTd_StaticDebug”不比對值“MDd_DynamicDebug”(main.obj 中)
1>libprotobufd.lib(common.obj) : error LNK2038: 檢測到“RuntimeLibrary”的不比對項: 值“MTd_StaticDebug”不比對值“MDd_DynamicDebug”(main.obj 中)
... ...
A:
此問題是因為在
protobuf.sln
下編譯
libprotobuf
和
protoc
兩個項目的工程屬性中的運作時庫與helloworld工程的運作時庫不一緻導緻的,将兩者運作時庫修改為一緻即可。
修改路徑為:[配置屬性]->[C/C++]->[代碼生成]->[運作庫]
libprotobuf
和
protoc
項目的工程屬性預設運作時庫為:
Debug : 多線程調試 (/MTd)
Release:多線程 (/MT)
本文中所述的項目資源已上傳至CSDN,可按需下載下傳。
該工程包含了x86/x64的Debug/Release 共計4個版本,且均編譯通過,可拿來即用。
下載下傳連結: google protobuf 初學者 helloworld VS2017 + protobuf-3.19.0 工程示例