MinGW编译protobuf,并在Qt中使用
protobuf是一个很好的序列化工具, 因为其二进制序列化,确保了数据传输的保密性和占用带宽小的特性,并且数据结构前后兼容。用来保存数据和传输数据都是非常不错的选择。Qt是非常优秀的跨平台UI框架,特别是其Qt Quick框架在移动平台的渲染效率相当不错,C++和QML结合的开发方式可以提高不少开发效率。
环境: Win7 x64
Qt5.7 forWindows MinGW版
protobuf-cpp-3.3.0.zip
一、编译protobuf
Qt使用protobuf有2种办法, 一种是直接用Qt编译protobuf的源码, 但这种方式各种报错,路途艰辛,GitHub上有别人做好的Qt项目但是版本较老,我用Qt5.7编译报错。另外就是用MinGW编译protobuf源码了,这个方法比较简单,容易成功。
1 下载安装CMake ,安装的时候选择添加环境变量, 我下载的版本cmake-3.9.0-rc5-win64-x64.msi
2 下载安装MinGW, (Qt 5.7自带的MinGW版本为5.3.0, 因此下载5.3.0的版本,避免不必要的麻烦)
进官网https://sourceforge.net/projects/mingw/files/点击"Download mingw-get-setup.exe (86.5 kB)"
下载完双击.exe文件安装,点击basic setup,然后依次右键单击,选择Mark for installation, 一定要勾选msys。然后点击菜单栏installation->Apply changes。安装过程比较慢,请耐心等待。安装完成后如下图所示。
安装完成后,将c:\minGW\bin和c:\minGW\msys\1.0\bin添加到系统变量里。
3 下载protobuf, 源代码包没有configure脚本,所以下载release版的源码包,地址:https://github.com/google/protobuf/releases
我下载的版本protobuf-cpp-3.3.0.zip, 下载完成后解压,我的路径是C:\XXXXX\QtProtobuf\protobuf-cpp-3.3.0\protobuf-3.3.0
我下载的版本protobuf-cpp-3.3.0.zip, 下载完成后解压,我的路径是C:\XXXXX\QtProtobuf\protobuf-cpp-3.3.0\protobuf-3.3.0
4 进入MinGW安装路径 C:\MinGW\msys\1.0, 双击msys.bat运行终端
在终端里进入之前一步解压的protobuf路径, 能看到如下所示的文件:
输入
./configure
make
开始编译
make
开始编译
编译过程中出现: 错误"'strdup' was not declared in this scope "
原因是strdup属于GNU C++的函数, 不是标准(std)C++的函数, 把Makefile中的"-std=C++11"修改为"-std=gnu++0x", 即可.
打开源码目录src文件夹, 打开Makefile文件
其中有2行(1080,1081行)
CXX = g++ -std=C++11
CXXCPP = g++ -E -std=C++11
修改为
CXX = g++ -std=gnu++0x
CXXCPP = g++ -E -std=gnu++0x
再次执行
make
make install
不出意外编译OK
安装的库和头文件在C:\MinGW\msys\1.0\local内
二、 Qt 5.7 使用 protobuf库
1 新建Qt 控制台工程在项目文件.pro中添加如下行
INCLUDEPATH += C:\MinGW\msys\1.0\local/include
LIBS += -L C:\MinGW\msys\1.0\local/lib -lprotobuf
2 编写一个简单的proto文件 config.proto, 内容如下
syntax = "proto3";
package config;
message VoiceConfig{
int32 sample_rate = 1;
int32 mic_num = 2;
string voiceserver_address = 3;
int32 wakeup_sensitivity = 4 ;
int32 bargein_sensitivity = 5;
int32 audo_outtype = 6;
}
打开msys终端,进入config.proto这个文件的路径
执行 protoc --cpp_out=. config.proto , 会在当前路径下生成两个文件config.pb.h,
config.pb.cc
。将这两个文件加入Qt工程.
2 在man函数中加入如下内容,
#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <string>
#include <config.pb.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
config::VoiceConfig vc;
QString ipaddr="192.168.0.136";
std::string s = ipaddr.toStdString();
vc.set_sample_rate(32000);
vc.set_allocated_voiceserver_address(&s);
vc.set_wakeup_sensitivity(50);
vc.set_bargein_sensitivity(50);
vc.set_audo_outtype(1);
std::string sdata="";
vc.SerializeToString(&sdata);
qDebug()<<"size:"<<sdata.size();
config::VoiceConfig de;
de.ParseFromString(sdata);
qDebug()<<"sample_rate:"<<de.sample_rate();
qDebug()<<"address:"<<QString::fromStdString(de.voiceserver_address());
qDebug()<<"wakeup_sensitivity:"<<de.wakeup_sensitivity();
return a.exec();
}
点击编译
编译成功但是运行报错During startup program exited with code 0xc0000135
这是因为用到了外部的dll库,lib库是以动态链接方式添加到了.pro文件的(可以静态链接到.pro),所以编译时不会出错,但是运行的时候就会报错
需要把dll库拷贝到程序执行路径,
拷贝C:\MinGW\msys\1.0\local\bin\libprotobuf-13.dll 到 程序的执行路径XXXXXX/debug
再次运行OK, 如下: