Protocol Buffers(protobuf)主要用于在不同系统、不同语言之间进行高效的数据序列化和反序列化。从而实现跨平台、跨语言的数据交互、网络通信、持久化存储等问题的工具。
在 C++ 中使用 Protobuf 需要先将源代码编译成指定平台的库,我们以 windows 为例,来演示下如何编译、安装,以及在 Visual Studio 中配置 Protobuf 。
- protobuf 安装工具 {#title-0} ===========================
- 安装 cmake:https://cmake.org/
- 安装 visuao studio 2022
- 下载 protobuf: https://github.com/protocolbuffers/protobuf/releases
- 解压
protobuf-27.1.zip
,并进入到protobuf-27.1/third_party
目录,使用下面命令下载第三方库
git clone https://github.com/abseil/abseil-cpp.git
- protobuf 编译设置 {#title-1} ===========================
- 打开
cmake-gui
图形界面
点击 Configure,此时可能会出现以下错误。此时,将 protobuf_BUILD_TESTS
选项取消勾选。
如果配置报错的话,请将 ABSL_PROPAGATE_CXX_STD
选项勾选。此时,所有的编译选项如下图所示(注意设置安装目录):
- protobuf_WITH_ZLIB: 控制是否编译安装 zlib 库。Zlib 是一个用 C 语言编写的压缩库,Protobuf 在一些情况下可能会用到它
- utf8_range_ENABLE_INSTALL: 控制是否安装 utf8_range 库。utf8_range 是一个处理 UTF-8 字符串范围的 C++ 库
- protobuf_INSTALL: 设置是否支持库安装。如果设置为 ON,将安装 Protobuf 库
- CMAKE_INSTALL_PREFIX: 设置库的安装路径。它指定了在 install 时库文件将被安装到哪个目录
- protobuf_BUILD_PROTOBUF_BINARIES: 控制是否构建 Protobuf 的二进制库文件
- protobuf_BUILD_PROTOC_BINARIES: 控制是否构建 protoc 编译器的。protoc 用来将 .proto 文件编译成对应的语言代码
- protobuf_BUILD_SHARED_LIBS: 制是否编译为动态库或共享库。如果设置为 ON,Protobuf 将被编译为共享库;如果设置为 OFF,Protobuf 将被编译为静态库
- ABSL_PROPAGATE_CXX_STD: 控制是否传递 C++ 标准设置给 Abseil 库。Abseil 是一个 Google 开源的 C++ 库,用于提供字符串处理、并发、调试等功能
- CMAKE_CONFIGURATION_TYPES: 指定生成的项目配置类型(如 Debug、Release 等)
最后,点击 Generate,生成 Visual Studio 项目。
- protobuf 开始编译 {#title-2} ===========================
- 在 cmake 设置的输出目录中,双击
protobuf.sln
文件,使用 Visual Studio 打开该项目。
在 Visual Studio 中选择编译的库类型 Debug 或者 Release、x32 或者 x64,我们这里选择 Release | x64 模式。然后点击生成,开始编译 protobuf 库文件。
编译完成之后,进入到设置的输出目录 (桌面 my-protobuf 目录)
,执行安装命令,将头文件、库文件拷贝到先前设置的安装目录下 (桌面 my 目录)
。
cmake --install .
安装完毕后,在 my 目录下会出现所需要的头文件、库文件,如下图所示:
- protobuf 配置项目 {#title-3} ===========================
将 Protobuf 配置到 Visual Studio 项目中,无非就两个要求:
- 能够找得到头文件
- 能够找得到库文件
接下来,演示详细的配置过程:
- 首先,创建 visual studio 项目,并设置为
Release 64 模式
- 然后,
属性->C/C++->代码生成->运行库 设置为 多线程(/MT)
,点击应用->确定 - 配置头文件路径
- 配置库文件路径
- 配置库文件名字
import glob
import os
if __name__ == '__main__':
fnames = glob.glob('C:/Program Files/protobuf/lib/*.lib')
libs = [os.path.basename(fname) for fname in fnames]
print('\n'.join(libs))
库文件名字:
absl_bad_any_cast_impl.lib
absl_bad_optional_access.lib
absl_bad_variant_access.lib
absl_base.lib
absl_city.lib
absl_civil_time.lib
absl_cord.lib
absl_cordz_functions.lib
absl_cordz_handle.lib
absl_cordz_info.lib
absl_cordz_sample_token.lib
absl_cord_internal.lib
absl_crc32c.lib
absl_crc_cord_state.lib
absl_crc_cpu_detect.lib
absl_crc_internal.lib
absl_debugging_internal.lib
absl_demangle_internal.lib
absl_die_if_null.lib
absl_examine_stack.lib
absl_exponential_biased.lib
absl_failure_signal_handler.lib
absl_flags_commandlineflag.lib
absl_flags_commandlineflag_internal.lib
absl_flags_config.lib
absl_flags_internal.lib
absl_flags_marshalling.lib
absl_flags_parse.lib
absl_flags_private_handle_accessor.lib
absl_flags_program_name.lib
absl_flags_reflection.lib
absl_flags_usage.lib
absl_flags_usage_internal.lib
absl_graphcycles_internal.lib
absl_hash.lib
absl_hashtablez_sampler.lib
absl_int128.lib
absl_kernel_timeout_internal.lib
absl_leak_check.lib
absl_log_entry.lib
absl_log_flags.lib
absl_log_globals.lib
absl_log_initialize.lib
absl_log_internal_check_op.lib
absl_log_internal_conditions.lib
absl_log_internal_fnmatch.lib
absl_log_internal_format.lib
absl_log_internal_globals.lib
absl_log_internal_log_sink_set.lib
absl_log_internal_message.lib
absl_log_internal_nullguard.lib
absl_log_internal_proto.lib
absl_log_severity.lib
absl_log_sink.lib
absl_low_level_hash.lib
absl_malloc_internal.lib
absl_periodic_sampler.lib
absl_random_distributions.lib
absl_random_internal_distribution_test_util.lib
absl_random_internal_platform.lib
absl_random_internal_pool_urbg.lib
absl_random_internal_randen.lib
absl_random_internal_randen_hwaes.lib
absl_random_internal_randen_hwaes_impl.lib
absl_random_internal_randen_slow.lib
absl_random_internal_seed_material.lib
absl_random_seed_gen_exception.lib
absl_random_seed_sequences.lib
absl_raw_hash_set.lib
absl_raw_logging_internal.lib
absl_scoped_set_env.lib
absl_spinlock_wait.lib
absl_stacktrace.lib
absl_status.lib
absl_statusor.lib
absl_strerror.lib
absl_strings.lib
absl_strings_internal.lib
absl_string_view.lib
absl_str_format_internal.lib
absl_symbolize.lib
absl_synchronization.lib
absl_throw_delegate.lib
absl_time.lib
absl_time_zone.lib
absl_vlog_config_internal.lib
libprotobuf-lite.lib
libprotobuf.lib
libprotoc.lib
utf8_range.lib
utf8_validity.lib
还有另外一种方法,在项目中新建筛选器,并在筛选器中添加现有项,将所有的 lib 文件添加到筛选器中。