天天看點

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

從零開始建構 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檔案,并運作

      protoc.exe

      生成對應的.h和.cc檔案
    • 将protobuf引入自己的工程使用

1. 下載下傳protobuf

  • 下載下傳protobuf

下載下傳位址: https://github.com/protocolbuffers/protobuf/releases

目前最新版本為3.19.0,在下載下傳頁面中直接下載下傳

protobuf-cpp-3.19.0.zip

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

注意:

若不想自己編譯,想下載下傳項目編譯好的release檔案時,在将protobuf引入自己的工程後,再編譯時會提示缺少檔案。

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程
報錯資訊為:
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

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

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

    )
從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程
  • 步驟2

在紅色背景框區域可更改預設生成配置,更改完成後點選

Configure

按鈕更新配置,随後點選

Generate

按鈕生成vs工程。

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程
  • 步驟3

    等待vs工程生成成功後,即可點選

    Open Project

    打開protobu的VS工程。
從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程
在最後一步可直接單擊

Open Project

按鈕,cmake可直接調用VS2017打開protobuf的VS解決方案工程檔案。

也可以自己去

E:\TestProj\protobuf-cpp-3.19.0\build

目錄用

VS2017

打開

protobuf.sln

檔案。
從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

3. vs編譯protobuf工程

在打開的protobuf工程中分别編譯

libprotobuf

protoc

這兩個項目。(其他項目編譯與否,請看自己的實際情況)。正常情況下,僅編譯

libprotobuf

protoc

兩個項目已經可以滿足核心需要。

  • 以debug為例,生成一下檔案:libprotobufd.lib、libprotocd.lib和protoc.exe
從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

debug版本生成的檔案如下圖

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程
  • 以release為例,生成一下檔案:libprotobuf.lib、libprotoc.lib和protoc.exe
從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

release版本生成的檔案如下圖

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

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

定義了一個消息名稱為

helloworld

的消息類型,該消息有2個成員,類型為 int32 的 id,另一個為類型為 string 的成員 str。

使用

protoc.exe

對消息進行處理,生成C++編譯器可識别的

.h

.cc

檔案

生成指令如下:(在使用時要注意.exe和.proto檔案的路徑)。

protoc.exe -I=. --cpp_out=. ./helloworld.proto
           
不知道 proto.exe的參數含義時,可使用

protoc.exe --help

指令檢視幫助文檔。

可參照下圖:

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

5. 将protobuf引入自己的工程

此處以Debug版本為例

  • 生成helloworld工程

    使用vs2017自己生成一個helloworld測試工程。

  • 拷貝依賴項

    将生成的

    libprotobufd.lib、libprotocd.lib和protoc.exe

    檔案拷貝至項目的lib目錄。(注意:本文使用的是靜态庫,若需要動态庫,則需在cmake階段選擇生成dll動态庫)
  • 拷貝頭檔案

    将源碼

    E:\TestProj\protobuf-cpp-3.19.0\protobuf-3.19.0\src

    下的

    google

    檔案夾拷貝至helloworld項目的

    include

    檔案夾
文字說明:
  • 在VS工程中,配置以下工程屬性:

[配置屬性]->[C/C++]->[正常]->[附加包含目錄]

: 添加

google

檔案夾所在路徑,預設在項目的include下

[配置屬性]->[連接配接器]->[正常]->[附加庫目錄]

: 添加

libprotobufd.lib

libprotocd.lib

檔案所在路徑

[配置屬性]->[連接配接器]->[輸入]->[附加依賴項]

:添加

libprotobufd.lib

libprotocd.lib

  • 在代碼頁中配置:
直接在需要寫消息的cpp檔案中 #include “helloworld.pb.h”

也可按下述例圖進行配置。

項目檔案目錄

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

檔案拷貝後的目錄為:

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

解決方案

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

修改附加包含目錄

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

修改附加庫目錄

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

修改附加依賴項

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

// 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)

從零開始建構Google Protocol Buffer / protobuf 的helloworld工程從零開始建構 Protocol Buffer / protobuf 的helloworld工程

本文中所述的項目資源已上傳至CSDN,可按需下載下傳。

該工程包含了x86/x64的Debug/Release 共計4個版本,且均編譯通過,可拿來即用。

下載下傳連結: google protobuf 初學者 helloworld VS2017 + protobuf-3.19.0 工程示例

繼續閱讀