先来看看效果。
1 安装Protobuf和CMake
下载protobuf-cpp源码,写本文时最新版本为3.13.0:https://github.com/protocolbuffers/protobuf/releases
如果电脑之前没安装CMake,需要先下载安装CMake,用于编译protobuf-cpp源码。
CMake下载地址:https://cmake.org/download/
2 CMake编译protobuf-cpp
打开CMake软件。
Where is the source code 项选择我们下载的protobuf-cpp源码目录下的cmake文件夹。
Where to build the binaries 项选择源码编译后存放的目录。
然后弹出一个对话框,叫选择生成哪种VS版本的项目,由于我用的VS2017,所以我选择的是Visual Studio 15 2017(ps:我试过选择Visual Studio 15 2017 Win64来创建64位的版本,但是后来发现生成的lib不能用,一直报错说生成的lib是32位的,所以我这儿就没选64位的版本)。
然后点击Finish,稍等编译完成。
出现以下界面后,点击Generate。
然后再点击Open Project,或者直接去编译后的目录用相应版本的VS打开生成后的项目。
然后选择生成libprotobuf、libprotoc、protoc这三个项目。
生成的文件如下(Debug模式下生成的文件在Debug文件夹下,Release模式下生成的文件在Release文件夹下),其中两个lib文件是c++程序需要引入的,protoc.exe用于编译.proto文件。
3 批处理生成proto文件
我们先编写一个测试用的proto文件。具体的proto的语法可以参考这篇文章。
syntax = "proto3";
package School;
message Student {
string name = 1;
int32 id = 2;
}
我们可以用命令行的方式来进行编译proto文件,一个proto文件会编译成一个pb.h和一个pb.cc文件。命令如下:
protoc --cpp_out=./cpp message.proto
但是由于实际项目中我们会写很多个proto文件,一个一个去编译proto文件很显然是不现实的,应该交给批处理程序,由于MFC默认包含有预编译头文件,而protoc默认没有添加预编译头,这里批处理程序中也需要添加预编译头。这里直接给出批处理编译proto文件的程序(rum.bat),如下。注意要将批处理程序和protoc.exe放在同一目录下。
@echo off
rem 进入当前目录
cd /d %~dp0
if not exist .\cpp (
md .\cpp
)
for %%i in (*.proto) do (
protoc --cpp_out=.\cpp %%i
rem 从这里往下都是注释,可忽略
echo From %%i To %%~ni.pb.h %%~ni.pb.cc Successfully!
)
rem 给.cc文件添加预编译头,若不需要,需注释掉以下部分
echo #include "pch.h" > $
for /f "delims=" %%i in ('dir /b .\cpp\*.pb.cc')do (
copy /b $+".\cpp\%%i" $1
move $1 ".\cpp\%%i"
)
del /f $
4 MFC项目中引用protobuf
首先创建一个MFC项目,然后选择显示所有文件。
接下来我们进行项目的配置。
第一步,右键项目名,选择属性,选择 配置属性》常规》MFC的使用,选择在静态库中使用MFC
注意,配置( C ) 要选择为 所有配置 平台( P ) 要选择为所有平台。
第二步,拷贝protobuf/src文件夹下的google至项目中。
然后设置项目属性,C/C++》常规》附加包含目录,添加上$(ProjectDir)。
注意,配置( C ) 要选择为 所有配置 平台( P ) 要选择为所有平台。
第三步,设置预处理器,项目属性,C/C++》预处理器》预处理器定义,添加_SCL_SECURE_NO_WARNINGS
第四步,创建一个lib/protobuf/x86文件夹,将之前生成的libprotobufd.lib拷贝过去,然后右键libprotobufd.lib包含在项目中。
第五步设置链接器。
①项目属性》链接器》常规》附加库目录 添加 $(ProjectDir)lib\protobuf\x86。
我这里没有生成64位的lib(所以我这儿配置( C )仍然选择的是所有配置,平台( P )仍然选择的所有平台),如果需要打包成64位的,建议创建一个x64的文件夹,然后把64位的lib拷贝过去。
②项目属性》链接器》输入》附加依赖项 添加libprotobufd.lib
(ps: 建议这里Debug模式配置为libprotobufd.lib,Release配置为libprotobuf.lib,因为我这儿只生成了Debug的lib文件,所以都用的libprotobufd.lib,实际项目最好改一下)
5 项目使用protobuf
创建src/proto文件夹,并把protoc.exe、run.bat以及我们写的proto文件拷贝至proto文件夹下。
双击run.bat,生成pb.h和pb.cc文件,点击刷新,并将pb.cc和pb.h包含在项目中。
至此,就可以在项目中愉快的使用protobuf啦。
序列化。
School::Student student;
student.set_name("Tom Cat");
student.set_id(999);
std::fstream output("./student.data", std::ios::out | std::ios::binary);
if (!student.SerializeToOstream(&output)) {
MessageBoxW(_T("序列化失败"));
}
else
{
MessageBoxW(_T("序列化成功"));
}
反序列化。
School::Student student;
std::fstream input("./student.data", std::ios::in | std::ios::binary);
if (!student.ParseFromIstream(&input)) {
MessageBoxW(_T("读取失败"));
}
else
{
CString msg;
msg.Format(_T("name:%S\r\nid:%d"), student.name().c_str(), student.id());
MessageBoxW(msg);
}
项目上传到这儿啦。
链接:https://pan.baidu.com/s/1kClVNeeWXzqJQCkKmR9G1Q
提取码:rhxr
博主本文博客链接。