从零开始构建Google Protocol Buffer / protobuf 的helloworld工程(超级详细)

从零开始构建 Google Protocol Buffer / protobuf 的helloworld工程

从零开始构建 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

download_protobuf.png

注意:

若不想自己编译,想下载项目编译好的release文件时,在将protobuf引入自己的工程后,再编译时会提示缺少文件。

download_protobuf_release.png

报错信息为:

fatal error C1083: 无法打开包括文件: “google/protobuf/port_def.inc”: No such file or directory

  
  
   
   
  • 1

实际去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

download_cmake.png

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的弹出界面中仿照下图进行配置。(此处编译平台选择为VS2017x64)

cmake_step1-comment.png

  • 步骤2

在红色背景框区域可更改默认生成配置,更改完成后点击Configure按钮更新配置,随后点击Generate按钮生成vs工程。

cmake_step2-comment.png

  • 步骤3

    等待vs工程生成成功后,即可点击Open Project打开protobu的VS工程。

cmake_step3-comment.png

在最后一步可直接单击Open Project 按钮,cmake可直接调用VS2017打开protobuf的VS解决方案工程文件。

也可以自己去E:\TestProj\protobuf-cpp-3.19.0\build目录用VS2017打开protobuf.sln文件。
open_project.png

3. vs编译protobuf工程

在打开的protobuf工程中分别编译 libprotobufprotoc这两个项目。(其他项目编译与否,请看自己的实际情况)。正常情况下,仅编译 libprotobufprotoc两个项目已经可以满足核心需要。

  • 以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

定义了一个消息名称为 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 命令查看帮助文档。

可参照下图:

在这里插入图片描述

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.liblibprotocd.lib文件所在路径

[配置属性]->[连接器]->[输入]->[附加依赖项] :添加 libprotobufd.liblibprotocd.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); // 序列化消息

<span class="token comment">//解析消息</span>
hellopb<span class="token operator">::</span>helloworld msgread<span class="token punctuation">;</span>
msgread<span class="token punctuation">.</span><span class="token function">ParseFromArray</span><span class="token punctuation">(</span>buff<span class="token punctuation">,</span> <span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
std<span class="token operator">::</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"id:"</span> <span class="token operator">&lt;&lt;</span> msgread<span class="token punctuation">.</span><span class="token function">id</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
std<span class="token operator">::</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"str:"</span> <span class="token operator">&lt;&lt;</span> msgread<span class="token punctuation">.</span><span class="token function">str</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>

}

运行后输出为:

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下编译libprotobufprotoc两个项目的工程属性中的运行时库与helloworld工程的运行时库不一致导致的,将两者运行时库修改为一致即可。

修改路径为:[配置属性]->[C/C++]->[代码生成]->[运行库]

libprotobufprotoc项目的工程属性默认运行时库为:

Debug : 多线程调试 (/MTd)

Release:多线程 (/MT)

在这里插入图片描述

本文中所述的项目资源已上传至CSDN,可按需下载。
该工程包含了x86/x64的Debug/Release 共计4个版本,且均编译通过,可拿来即用。
下载链接: google protobuf 初学者 helloworld VS2017 + protobuf-3.19.0 工程示例

这是我2022年第一篇文章,也是第一次转载别人的文章。

原文出处:https://blog.csdn.net/shadow_2011/article/details/121017458

猜你喜欢

转载自blog.csdn.net/jianjianshini/article/details/125538104