天天看点

从零开始构建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 工程示例

继续阅读