测试环境:
windows10 x64
vs2019
cmake==3.26.3
protobuf==3.15.0
0. 前言
- 由于对 Windows 和 VS2019 不太熟悉,在编译并使用 Protobuf 的过程中碰到很多问题,虽然没有完全解决,但勉强能用,这里记录一下。
- 目标:
- 使用VS2019编译 Protobuf
- VS2019 项目中使用编译好的 Protobuf
- Windows下的 CMake 项目中,引用编译好的 Protobuf
1. VS2019 编译 Protobuf
- 准备工作:
- 安装好 cmake
- 下载好 Protobuf 的源码
- 第一步:使用打开 cmake-gui 配置 Protobuf,如下图所示
- 要做的就是:选择并设置cmake对象,点击
configure
,然后点击renerate
,生成好后点击open project
- 需要配置的参数包括:
protobuf_BUILD_SHARED_LIBS
:需选中该选项,则可编译动态链接库CMAKE_INSTALL_PREFIX
:程序编译完成后安装的路径,默认在C盘,要求VS2019有管理员权限。protobuf_WITH_ZLIB
:取消选中该选项
- 要做的就是:选择并设置cmake对象,点击
- 第二步:在VS2019中编译源码
- 选择下面三个选项,分别右键点击选择
生成
- 最终在
CMAKE_INSTALL_PREFIX
目录下获得对应的 lib/dll 文件以及头文件。 - 注意:需要将
${CMAKE_INSTALL_PREFIX}/bin
目录添加到环境变量PATH
中,这样才能在命令行中使用protoc
命令。
- 选择下面三个选项,分别右键点击选择
3. VS2019 项目中使用编译好的 Protobuf
- 目标:创建一个空项目,引入编译好的 Protobuf 并使用。
- 第一步:创建一个名为
protobuf_demo
的空项目。 - 第二步:创建
person.proto
,并生成 C++ 原文件。person.proto
如下所示- 转换命令为
protoc --cpp_out=./ person.proto
,生成了person.pb.h
和person.pb.cc
- 注意:需要在
person.pb.h
中添加#define PROTOBUF_USE_DLLS
,不然编译会报错
syntax = "proto3";
package tutorial;
message Person {
string name = 1;
int32 id = 2;
string email = 3;
}
- 第三步:编写测试代码
#include "person.pb.h"
#include <iostream>
int main() {
tutorial::Person person;
person.set_id(1);
person.set_email("john@gmail.com");
person.set_name("John");
std::cout << person.SerializePartialAsString() << std::endl;;
return 0;
}
- 第四步:VS2019 相关设置 - 添加源码到解决方案
- 第五步:设置 protobuf 相关 VS2019 设置
- 假设 protobuf 的安装路径是
C:\Program Files (x86)\protobuf
项目 -> 属性 -> VC++目录 - > 包含目录
:设置头文件路径为C:\Program Files (x86)\protobuf\include
项目 -> 属性 -> VC++目录 -> 库目录
:设置lib文件路径C:\Program Files (x86)\protobuf\lib
项目 -> 链接器 -> 输入 -> 附加依赖项
中添加libprotobufd.lib
- 将
C:\Program Files (x86)\protobuf\bin
添加到系统路径PATH
中
- 假设 protobuf 的安装路径是
- 第六步:编译源码并运行
- 右键点击解决方案,然后选择生成
4. VS2019 的 CMake 项目中引入 Protobuf
-
源码以及proto文件生成请参考第三章
- 注意,需要在
*.ph.h
最前面添加#define PROTOBUF_USE_DLLS
- 注意,需要在
-
一般引入(即通过
find_package
引入)- 在 protobuf 安装路径中其实有
cmake
配置文件 - Linux 中成功通过
find_package(Protobuf)
以及Protobuf_INCLUDE_DIRS
和Porotuf_LIBRARIES
引入头文件和库文件。 - 本人在两台电脑上做了类似的操作,一台电脑成功了,一台失败了。
- 成功的电脑:Protobuf 安装在
C:\Program Files (x86)\protobuf
中,find_package
以及各种参数都能正常使用。 - 失败的电脑:Protobuf 安装在源码路径下,
find_package
失败。
- 成功的电脑:Protobuf 安装在
- 在 protobuf 安装路径中其实有
-
手动引入
- 如果不能通过
find_package
引入 Protobuf,就需要手动将 protobuf 的头文件路径、链接文件路径等手动引入CMakeLists.txt
中。 - 换句话说,需要手动设置
Protobuf_INCLUDE_DIRS
和Protobuf_LIBRARIES
两个参数。 - 假设Protobuf的安装路径是
D:/vs/protobuf-3.20.1/vs_x64_out
,那么CMakeLists.txt 文件形式可以参考下面
- 如果不能通过
# 一般引入方法(二选一)
find_package(Protobuf)
# 手动引入方法(二选一)
SET(Protobuf_INSTALL_DIR D:/vs/protobuf-3.20.1/vs_x64_out)
include_directories("${Protobuf_INSTALL_DIR}/include")
link_directories("${Protobuf_INSTALL_DIR}/lib")
SET(Protobuf_LIBRARIES libprotobufd libprotocd)
# 公用代码
include_directories(${Protobuf_INCLUDE_DIRS})
add_executable (protoc_demo protoc_demo.cpp person.pb.cc)
target_link_libraries(protoc_demo ${Protobuf_LIBRARIES})