Protobuf linux和windows下编译与使用

时间:2024-05-30 18:41:24

Google的probobuf是一个非常好用的序列化和反序列化库,而且它是跨平台的。如果应用需要在linux和windows下跨平台运行, protobuf是一个不错的选择。

这里介绍一下Protobuf linux和windows下编译与使用。

1 Download and build

Download from:

https://github.com/protocolbuffers/protobuf/releases

 

protobuf-cpp-3.12.4.tar.gz

 

./configure

 make

 make check

 sudo make install

 sudo ldconfig # refresh shared library cache.

 

 

/usr/local/bin/protoc

/usr/local/include/google/protobuf

/usr/local/lib/

-rwxr-xr-x 1 root root    5518672 8月   4 16:17 libprotobuf-lite.so.23.0.4

lrwxrwxrwx 1 root root         26 8月   4 16:17 libprotobuf-lite.so.23 -> libprotobuf-lite.so.23.0.4

lrwxrwxrwx 1 root root         26 8月   4 16:17 libprotobuf-lite.so -> libprotobuf-lite.so.23.0.4

-rwxr-xr-x 1 root root       1012 8月   4 16:17 libprotobuf-lite.la

-rwxr-xr-x 1 root root   35029840 8月   4 16:17 libprotobuf.so.23.0.4

lrwxrwxrwx 1 root root         21 8月   4 16:17 libprotobuf.so.23 -> libprotobuf.so.23.0.4

lrwxrwxrwx 1 root root         21 8月   4 16:17 libprotobuf.so -> libprotobuf.so.23.0.4

-rwxr-xr-x 1 root root        977 8月   4 16:17 libprotobuf.la

-rwxr-xr-x 1 root root   47564640 8月   4 16:17 libprotoc.so.23.0.4

lrwxrwxrwx 1 root root         19 8月   4 16:17 libprotoc.so.23 -> libprotoc.so.23.0.4

lrwxrwxrwx 1 root root         19 8月   4 16:17 libprotoc.so -> libprotoc.so.23.0.4

-rwxr-xr-x 1 root root        993 8月   4 16:17 libprotoc.la

-rw-r--r-- 1 root root   14213702 8月   4 16:17 libprotobuf-lite.a

-rw-r--r-- 1 root root   92705362 8月   4 16:17 libprotobuf.a

-rw-r--r-- 1 root root  144112782 8月   4 16:17 libprotoc.a

2 Windows build

这里介绍的方式是使用Visual Studio编译。

 

2.1安装cmake

首先需要在windows 上安装cmake。

 

2.2生成sln工程

解压protobuf-3.12.4包后,进入protobuf-3.12.4\cmake目录,创建

子目录: build\debug

启动powershell, 进入protobuf-3.12.4\cmake\build\debug目录,运行如下命令:

cmake -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=Debug

-Dprotobuf_BUILD_SHARED_LIBS=ON

-Dprotobuf_BUILD_TESTS=OFF

-Dprotobuf_MSVC_STATIC_RUNTIME=OFF

-DCMAKE_INSTALL_PREFIX=../../../install

-T host=x64 -A x64 ../..

几个参数说明:

protobuf_BUILD_SHARED_LIBS=ON 编译成动态库DLL 如果是需要静态库,不需要加此参数

-T host=x64 -A x64  :指定为windows x86_64 处理器,如果是32位的系统不需要加此参数。

 

命令运行完毕,会在protobuf-3.12.4\cmake\build\debug目录生成vs 工程文件,如下:

Protobuf linux和windows下编译与使用

 

2.3 编译

使用Visual Studio 2017打开工程文件protobuf.sln

因为我们只需要libprotobuf库,所以,只需要编译此库文件即可,其他的项目在编译时会报错,但是可以忽略,如下图所示:

Protobuf linux和windows下编译与使用

编译完成后,生成的库文件位于:protobuf-3.12.4\cmake\build\debug\Debug

Protobuf linux和windows下编译与使用 

3 usage使用

2.1 编写proto文件

例如:

message Person {

        required string name = 1;

        required int32 id = 2;

        optional string email = 3;

       

        enum PhoneType {

            MOBILE = 0;

            HOME = 1;

            WORK = 2;

        }

       

        message PhoneNumber {

            required string number = 1;

            optional PhoneType type = 2 [default = HOME];

        }

       

        repeated PhoneNumber phone = 4;

}

 

2.2 generate c++ code

protoc -I=./ --cpp_out=./ person.proto

 

[email protected]:/local/test$ ls

person.pb.cc  person.pb.h  person.proto

 

所幸的是, 在Linux下和在windows下生成的文件是一样的(当然要除去回车和换行的区别),这样,只需要生成一次就可以跨平台使用了。

2.3 write to file

write.cc

#include <iostream>

#include <fstream>

#include <person.pb.h>

using namespace std;

int main()

{

    Person person;

    person.set_name("John Doe");

    person.set_id(1234);

    person.set_email("[email protected]");

    fstream output("./myfile", ios::out | ios::binary);

    person.SerializeToOstream(&output);

 

    return 0;

}

Compile:

g++ -o write  person.pb.cc write.cc -I/usr/local/include -I./ -L/usr/local/lib -lprotobuf

 

2.4 read from file

Read.cc

#include <iostream>

#include <fstream>

#include <person.pb.h>

using namespace std;

int main()

{

    fstream input("myfile", ios::in | ios::binary);

    Person person;

    person.ParseFromIstream(&input);

    cout << "Name: " << person.name() << endl;

    cout << "E-mail: " << person.email() << endl;

    return 0;

}

g++ -o read person.pb.cc read.cc -I/usr/local/include -I./ -L/usr/local/lib -lprotobuf

 

4 trouble shooting

在windows使用protobuf库时,会报如下错误:

错误 LNK2001 无法解析的外部符号 "class google::protobuf::internal::ExplicitlyConstructed<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > google::protobuf::internal::fixed_address_empty_string" ([email protected]@[email protected]@@[email protected][email protected]?

 

这时,可以使用如下方法:

1 在protobuf的头文件中inc\google\protobuf\port_def.inc

加上#define PROTOBUF_USE_DLLS

如下所示:

 Protobuf linux和windows下编译与使用

2 如此改动之后,又会报其他的错误:  不允许 dllimport 函数 的定义

parse_context.h文件中的PackedEnumParser, PackedEnumParserArg函数实现不需要import。

需要把函数前面的PROTOBUF_EXPORT_TEMPLATE_DEFINE删除