Protocol Buffers

504 阅读1分钟

卸载

sudo rm /usr/local/bin/protoc  //执行文件
sudo rm -rf /usr/local/include/google //头文件
sudo rm -rf /usr/local/lib/libproto* //库文件

官网地址

developers.google.cn/protocol-bu… 协议缓冲区是 Google 的语言中立、平台中立、可扩展的结构化数据序列化机制——想想 XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言。 是谷歌推出的一种轻便高效的结构化数据存储格式,把结构化的数据序列化。常用以存储数据、作为网络通信的数据载体。具有提供多种编程语言的 API、跨平台和可扩展的特性。比 JSON 和 XML 更小、解析速度更快、更易于程序员上手,

示例

syntax = "proto2";

package tutorial;

message Person {
  optional string name = 1;
  optional int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    optional string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

  • package 定义包名
  • optional 可选的
  • repeated 动态数组
  • required 必须的

编译生成

mkdir -p build/c# build/cpp build/java
protoc -I=protos --csharp_out=build/c# --cpp_out=build/cpp --java_out=build/java protos/Chunk.proto

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
protoc -I=protos --cpp_out=build/cpp protos/Chunk.proto

c++

developers.google.cn/protocol-bu…

Ubuntu 下安装protobuf

  • 下载源码
git clone https://github.com/protocolbuffers/protobuf.git
  • 安装依赖库

Protocol Buffer 是 C++ 编写的,主要是安装 g++ 编译器:

sudo apt-get install autoconf automake libtool curl make g++ unzip
  • 编译安装并更新共享库:
 ./autogen.sh
 ./configure
 make
 make check
 sudo make install
 sudo ldconfig

使用此方法在ubuntu下CmakeList中使用find_package(Protobuf REQUIRED)会找不到 所以要指定位置,如果您已经使用其他前缀构建了软件包,请确保在再次构建之前运行“ make clean”。

 make clean
 ./autogen.sh
 ./configure --prefix=/usr/local
 make
 make check
 sudo make install
 sudo ldconfig
  • 编译arm版本
 make clean
  ./autogen.sh
./configure --host=arm-linux CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ --with-protoc=.--with-protoc=protoc
 make -j16
 make check
 sudo make install
 sudo ldconfig

在安卓报错:ld: error: ../../../../src/main/jniLibs/arm64-v8a/libprotobuf3158.so is incompatible with aarch64linux

  • 编译android arm64-v8a版本
cd protobuf
#export ndk_root=/home/tang/Documents/protobuf/android-ndk-r21b
export ndk_root=/home/tang/Android/Sdk/ndk/22.1.7171670
cmake \
-Dprotobuf_BUILD_SHARED_LIBS=ON \
-Dprotobuf_BUILD_STATIC_LIBS=ON \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-Dprotobuf_BUILD_TESTS=OFF \
-Dprotobuf_BUILD_EXAMPLES=OFF \
-DCMAKE_TOOLCHAIN_FILE=$ndk_root/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=lib \
-DANDROID_NDK=$ndk_root \
-DANDROID_TOOLCHAIN=clang \
-DANDROID_ABI=arm64-v8a \
-DANDROID_NATIVE_API_LEVEL=23 \
-DANDROID_STL=c++_shared \
-DANDROID_LINKER_FLAGS="-landroid -llog" \
-DANDROID_CPP_FEATURES="rtti exceptions" \
./cmake
make -j16
  • 编译android armeabi-v7a版本
cd protobuf
export ndk_root=/home/tang/Android/Sdk/ndk/22.1.7171670
cmake 
-Dprotobuf_BUILD_SHARED_LIBS=ON 
-Dprotobuf_BUILD_STATIC_LIBS=ON
-DCMAKE_VERBOSE_MAKEFILE=ON 
-Dprotobuf_BUILD_TESTS=OFF 
-Dprotobuf_BUILD_EXAMPLES=OFF 
-DCMAKE_TOOLCHAIN_FILE=$ndk_root/build/cmake/android.toolchain.cmake 
-DCMAKE_BUILD_TYPE=Release 
-DCMAKE_INSTALL_PREFIX=lib 
-DANDROID_NDK=$ndk_root 
-DANDROID_TOOLCHAIN=clang 
-DANDROID_ABI=armeabi-v7a 
-DANDROID_NATIVE_API_LEVEL=23 
-DANDROID_STL=c++_shared 
-DANDROID_LINKER_FLAGS="-landroid -llog" 
-DANDROID_CPP_FEATURES="rtti exceptions"
./cmake
make -j16
  • 测试是否安装成功
protoc -h
protoc --version
  • 使用Protoc编译 proto 文件

protoc student.proto --cpp_out=./

将student.proto编译生成

student.pb.h:声明你生成的类的头文件。

student.pb.cc:你生成的类的实现文件。

和student.proto在同一目录下

  • 使用.pd.h .pd.cc

将所有生成的文件复制到项目中去,include “”对应的名称,就可以在main函数中使用了

  //调用caffe.pb.h中的Person类,并设置id以及name,通过调用add_phone()来添加number
    caffe::Person person;
    person.set_id(10421);
    person.set_name("hopo");
    person.set_email("2381892713@qq.com")
    //序列化
    Measurement::HR::Chunk chunk;
    Measurement::HR::Frame* frameadd;
    chunk.set_order(Measurement::HR::Chunk_OrderEnum_Last);
    chunk.set_number(1);
    frameadd = chunk.add_frames();
    frameadd->set_fps(30);
    frameadd->set_length(100);
    frameadd->add_green(111);
    frameadd->add_green(222);
    string chunstr = chunk.SerializeAsString();
    //反序列化
    Measurement::HR::Frame frame1;
    Measurement::HR::Chunk chunk1;
    chunk1.ParseFromString(chunstr);
    frame1 = chunk1.frames().Get(0);
    cout<<"chunstr:  \n"<<chunk1.DebugString()<<endl;
    cout<<"number  "<<chunk1.number()<<endl;
    cout<<"order  "<<chunk1.order()<<endl;
    cout<<"length  "<<frame1.length()<<endl;
    cout<<"green  "<<frame1.green().Get(0)<<endl;
    cout<<"fps  "<<frame1.fps()<<endl;
  • error This file was generated by an older version of protoc which is 原因是使用的protoc版本过低导致 下载最新版本的对应平台的protoc,如protoc-3.14.0-linux-x86_64 进入到bin目录。有protoc文件
sudo cp protoc /usr/bin/protoc

再检查版本就是最新的了

  • CmakeList.txt配置
cmake_minimum_required(VERSION 2.8)
PROJECT (cppTest)
SET(SRC_LIST main.cpp)

# Find required protobuf package
find_package(Protobuf REQUIRED)
if(PROTOBUF_FOUND)
    message(STATUS "protobuf library found")
else()
    message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()

include_directories(${PROTOBUF_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS AddressBook.proto)

ADD_EXECUTABLE(cppTest ${SRC_LIST} ${PROTO_SRCS} ${PROTO_HDRS})

target_link_libraries(cppTest ${PROTOBUF_LIBRARIES})
  • error: unknown type name 'PROTOBUF #PRAGMA INIT_SEG'

移除/usr/local/include下的google/protobuf/...文件夹

java

developers.google.com/protocol-bu…

  • 在app的build.gradle中添加依赖
dependencies {
    implementation 'com.google.protobuf:protobuf-java:3.15.8'
    }
  • 将生成的java连同文件夹复制到项目中去

Native C++

  • 新建Native C++项目

next

选择c++版本,一般选择C++11

点击finish