当前位置:网站首页>从零开始构建Google Protocol Buffer / protobuf 的helloworld工程(超级详细)
从零开始构建Google Protocol Buffer / protobuf 的helloworld工程(超级详细)
2022-08-10 05:35:00 【三和尚】
从零开始构建 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
注意:
若不想自己编译,想下载项目编译好的release文件时,在将protobuf引入自己的工程后,再编译时会提示缺少文件。
报错信息为:
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
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工程生成成功后,即可点击
Open Project
打开protobu的VS工程。
在最后一步可直接单击
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
定义了一个消息名称为
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++]->[常规]->[附加包含目录]
: 添加
[配置属性]->[连接器]->[常规]->[附加库目录]
: 添加libprotobufd.lib
和libprotocd.lib
文件所在路径
[配置属性]->[连接器]->[输入]->[附加依赖项]
:添加libprotobufd.lib
和libprotocd.lib
- 在代码页中配置:
直接在需要写消息的cpp文件中 #include “helloworld.pb.h”
也可按下述例图进行配置。
项目文件目录
文件拷贝后的目录为:
解决方案
修改附加包含目录
修改附加库目录
修改附加依赖项
// main.cpp
#include <iostream>
#include <fstream>
#include“msg/helloworld.pb.h”// 包含生成的头文件
intmain(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"><<</span> <span class="token string">"id:"</span> <span class="token operator"><<</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"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>
std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"str:"</span> <span class="token operator"><<</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"><<</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
下编译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 工程示例
这是我2022年第一篇文章,也是第一次转载别人的文章。
原文出处:https://blog.csdn.net/shadow_2011/article/details/121017458
边栏推荐
- STM32F407ZG 串口通信+固定帧头帧尾传输数据帧
- 过大数组导致爆栈的解决方法记录(堆栈)
- LeetCode 162. Finding Peaks (Moderate)
- WeChat applet wx.writeBLECharacteristicValue Chinese character to buffer problem
- LeetCode refers to offer 10-I. Fibonacci sequence (simple)
- C陷阱与缺陷 个人阅读笔记
- LeetCode 100. The same tree (simple)
- 卷积神经网络(CNN)实现mnist手写数字识别
- A little knowledge point every day
- Gradle学习(二)Groovy
猜你喜欢
51单片机教室人数进出统计检测数码管显示装置红外传感器
Notes for RNN and Decision Tree
Collection tool class
51单片机智能蓝牙APP加油站火灾预警安防防控报警监控系统MQ2DHT11
LeetCode 1720. Decoding XORed Arrays (Simple)
Convolutional Neural Network (CNN) for mnist handwritten digit recognition
LeetCode Interview Question 17.14 Minimum k Number (Moderate)
PyTorch之模型定义
Pytorch - 07. Multidimensional characteristics of input processing
LruCache与DiskLruCache结合简单实现ImageLoader
随机推荐
详解样条曲线(上)(包含贝塞尔曲线)
Convolutional Neural Network (CNN) for Clothing Image Classification
【从零设计 LaTex 模板】1. 一些基础知识
pytorch-11. Convolutional Neural Network (Advanced)
[List Exercise] Traverse the collection and sort by price from low to high,
STM32F407ZG 看门狗 IWDG & WWDG
pytorch-10.卷积神经网络
三种素数筛总结——(朴素筛,埃氏筛,线性筛)
Tensorflow 2.0 使用流程详解
I don't like my code
中间件-Rocktmq
【接口自动化】
系统架构和问题定位
序列化、编码、requests库json和data参数
微信小程序-小程序的宿主环境
LeetCode 1351.统计有序矩阵中的负数(简单)
MySQL中MyISAM为什么比InnoDB查询快
pytorch-10. Convolutional Neural Networks (homework)
Common class String overview
离散数学的学习记录