protobuf在使用时出现的问题小汇总

  文章开头放一下IBM的google protocol buffer的介绍链接。http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/

  对于这种技术不断更新的东西,我只能这么理解:因为技术在更新,版本在变化,之前很详尽的技术博文可能在之后的版本中遇到无法预知的问题,所以我们在使用时要注意甄别。废话不多说,进入正文部分。

  安装什么的都是小问题了,还是贴一下步骤吧。

 tar -xzf protobuf-2.5.0.tar.gz
 cd protobuf-2.5.0
 ./configure --prefix=$INSTALL_DIR
 make
 make check
 make install

  很简单的标准*nix的安装方法。随后将安装目录的bin目录下的protoc创建一个软连接到/usr/bin目录下即可。

  随后可以进行简单的例子测试了。我这里有一个测试例子:

file:base.taskinfo.proto

package base;

message funcinfo
{
        required        string  funchandle = 1;//处理函数列表
        optional    string  funcinit = 2;   //初始化函数
        optional    string  funcclean = 3;  //清理函数
}

message taskinfo
{
        required        int32   taskid = 1;             //任务id
        required        int32   pidcount = 2;   //进程数目
        required        string  filepath = 3;   //输入文件路径
        required        string  filename = 4;   //文件名
        required        string  temppath = 5;   //临时文件路径
        required        string  scriptpath = 6; //脚本路径
        required        funcinfo func = 7;              //函数信息
        required string redisconn = 8;  //redis链接ip及port
}

  然后用它来生成c++类型的相对应的文件:protoc --cpp_out=./ base.taskinfo.proto

  就生成了两个标准c++的头文件和源文件:base.taskinfo.pb.cc  base.taskinfo.pb.h

  然后就可以写简单的例子进行测试了,这里写了一个叫write.cpp的简单例子:(以下****部分涉及个人隐私,避免被人肉)

#include "base.taskinfo.pb.h"
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
        base::funcinfo func;
        func.set_funchandle("GetKeyVal");

        base::taskinfo msg1;
        msg1.set_taskid(1);
        msg1.set_pidcount(3);
        msg1.set_filepath("/data/home/****/data/basetest/indir");
        msg1.set_filename("CH_PW_WAY");
        msg1.set_temppath("/data/home/****/data/basetest/tmpdir");
        msg1.set_scriptpath("/data/home/****/data/basetest/perl/CH_PW_WAY.pl");
        msg1.set_allocated_func(&func);
        msg1.set_redisconn("10.200.25.155:7379");
        fstream output("./log", ios::out | ios::trunc | ios::binary);
        if (!msg1.SerializeToOstream(&output)) {
                cerr<<"Failed to write msg."<< endl;
                return -1;
        }
        return 0;
}

  然后就可以写个Makefile去编译这1个cpp,1个cc和1和h文件(protoc生成的.cc文件)

#makefile by ****
#2015年1月4日09:07:28
cc = g++
cpp = -fPIC -Wall -g

inc += -I./
inc += -I/soft/protobuf-2.5.0/include

libs += -L/soft/protobuf-2.5.0/lib -lprotobuf -lpthread

objs=$(patsubst %.cc,%.o, $(wildcard *.cc))
objs+=$(patsubst %.cpp,%.o, $(wildcard *.cpp))
%.o:%.cc
        $(cc) $(cpp) $(inc) -o [email protected] -c $<
        @echo "[email protected]"

%.o:%.cpp
        $(cc) $(cpp) $(inc) -o [email protected] -c $<
        @echo "[email protected]"

module=./writer

all:$(module)

$(module):$(objs)
        $(cc) $(cpp) $(inc) -o $(module) $^ $(libs)
        @echo "[email protected]"

clean:
        @rm -f $(objs) $(module)
        @echo "clean done."

编译没问题,然后很快乐的就生成了可执行文件

随后就是 执行,让他生成log文件就行了,执行的时候出现了无法找到lib的错误,好吧,把刚才的安装目录下的lib目录添加到环境变量$LD_LIBRARY_PATH中去,再执行就出现了:

*** glibc detected *** ./writer: munmap_chunk(): invalid pointer: 0x00007fff8521b9b0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x75358)[0x7fa138d93358]
./writer[0x4046f1]
./writer[0x403732]
./writer[0x4044ae]
./writer[0x409010]
/lib64/libc.so.6(__libc_start_main+0xe6)[0x7fa138d3cc36]
./writer[0x403099]
======= Memory map: ========

..以下省略数千个字符。总之就是core掉了。试试gdb工具,调试结果如下所示:

Missing separate debuginfo for /lib64/ld-linux-x86-64.so.2
Try: zypper install -C "debuginfo(build-id)=c81de241a528795f8dbfde0f0e0e236f9a6554e6"
Core was generated by `./writer‘.
Program terminated with signal 6, Aborted.
#0  0x00007fad42931b55 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007fad42931b55 in raise () from /lib64/libc.so.6
#1  0x00007fad42933131 in abort () from /lib64/libc.so.6
#2  0x00007fad4296ec2f in __libc_message () from /lib64/libc.so.6
#3  0x00007fad42974358 in malloc_printerr () from /lib64/libc.so.6
#4  0x00000000004046e1 in base::funcinfo::~funcinfo (this=0x7fff3026a2c0, __in_chrg=<optimized out>) at base.taskinfo.pb.cc:167
#5  0x0000000000403722 in base::taskinfo::SharedDtor (this=0x7fff3026a270) at base.taskinfo.pb.cc:537
#6  0x000000000040449e in base::taskinfo::~taskinfo (this=0x7fff3026a270, __in_chrg=<optimized out>) at base.taskinfo.pb.cc:517
#7  0x0000000000409000 in main () at writer.cpp:25

应该是析构函数出错了,看一下到底protoc给我们生成了什么东西吧。这段代码摘自base.taskinfo.pb.cc

void taskinfo::SharedDtor() {
  if (filepath_ != &::google::protobuf::internal::kEmptyString) {
    delete filepath_;
  }
  if (filename_ != &::google::protobuf::internal::kEmptyString) {
    delete filename_;
  }
  if (temppath_ != &::google::protobuf::internal::kEmptyString) {
    delete temppath_;
  }
  if (scriptpath_ != &::google::protobuf::internal::kEmptyString) {
    delete scriptpath_;
  }
  if (redisconn_ != &::google::protobuf::internal::kEmptyString) {
    delete redisconn_;
  }
  if (this != default_instance_) {
    delete func_;
  }
}

我擦。(请原谅我的粗鲁),居然是delete func_,我顿时就不能淡定了。我申请的是栈内存,你给我来个delete,不core才怪了~好吧,请原谅我没有看你这个生成的1061行的源代码。

改一下上面的write.cpp的代码:

#include "base.taskinfo.pb.h"
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
        base::funcinfo *func = new base::funcinfo();
        func->set_funchandle("GetKeyVal");

        base::taskinfo *msg1 = new base::taskinfo();
        msg1->set_taskid(1);
        msg1->set_pidcount(3);
        msg1->set_filepath("/data/home/****/data/basetest/indir");
        msg1->set_filename("CH_PW_WAY");
        msg1->set_temppath("/data/home/****/data/basetest/tmpdir");
        msg1->set_scriptpath("/data/home/****/data/basetest/perl/CH_PW_WAY.pl");
        msg1->set_allocated_func(func);
        msg1->set_redisconn("10.200.25.155:7379");
        fstream output("./log", ios::out | ios::trunc | ios::binary);
        if (!msg1->SerializeToOstream(&output)) {
                cerr<<"Failed to write msg."<< endl;
                return -1;
        }
        return 0;
}

好 编译运行没问题了,都解决了。生成了一个log文件,这文件没办法看了。内容按照他自己的格式写的,有一些乱码和一些能看得懂的,自己写进去的东西。

时间: 2024-10-21 18:36:08

protobuf在使用时出现的问题小汇总的相关文章

idea使用时遇到的一个小问题

使用idea开发 自带的mave 3可以使用,自己下载的maven3.5.2设置后总是报错 unable to import maven project maven安装没有问题  mvn -v 是正确的 从idea-help-show log in explorer 查看日志 发现 启动maven时 找不到 org.apache.maven.cli..下的一个class, 所以在idea中使用maven时error. 解决办法: 升级了下idea,就可以了. 根源:版本冲突导致的. 原文地址:h

EntityFrameWork 使用时碰到的小问题

EntityFrameWork 使用时碰到的小问题 1,在使用orm访问数据库的相目里,也要引用EntityFrameWork.dll,否则无法使用orm 否则,编译错误 错误 5 "System.Data.Entity.DbSet`1<DbAccess.Entity.Dept>"不包含"Where"的定义,并且找不到可接受类型为"System.Data.Entity.DbSet`1<DbAccess.Entity.Dept>&qu

bootstrap使用时 细节心得

最近国庆7天 还原某丽说 APP PC端网页(作业)时  全程使用bootstrap制作 也遇到了以前很少碰到过的问题 bootstrap 本身修改了某些默认样式  即使在 未给标签class命名某个bootstrap模板时  某些标签也被修改过  这样会容易使某些像我一样的新手误以为自己写的代码哪里出了问题  而浪费很多时间去找一个 没有错误的错误  所以在这里给各位同学做个温馨提示 例如 fieldset 中 lengd标签中的文字 应该是水平居中 位于两侧横线中间 并且垂直居中于横线 但在

MySQL服务启动:某些服务在未由其他服务或程序使用时将自动停止

这几天因为工作需求,需要把MySQL请出来,所以将尘封已久的MySQL进行启动.可是事与愿违,兴许是许久没有访问MySQL了,MySQL生气的不理我,并向外抛出一阵阵报错.1.其中一个是:Windows无法启动MySQL57服务(位于本地计算机上)错误1067:进程意外终止,报错如下图所示. 2.紧跟着还有一个报错:本地计算机上的MySQL服务启动后停止.某些服务在未由其他服务或程序使用时将自动停止,报错如下图所示. 3.之后即便我垂死挣扎,在命令行窗口中不断的重启MySQL服务,但是仍然没有戳

Highcharts使用时遇到的问题及解决方案

Highcharts使用时遇到的问题及解决方案 Highcharts图表控件功能强大,对细节处理得很细致,是目前使用最为广泛的图表控件.本文总结了作者在使用Highcharts时遇到的问题及解决方案. 1. 图表颜色设置 图表的边框色,背景色及点.线的颜色都是可以设置的,其中边框色(borderColor).背景色(backgroundColor)在chart中设置: chart: { backgroundColor: 'pink',// 背景色 borderColor: 'red',// 边框

c语言:宏里面参数不加括号容易出错,在使用时尽量加括号及举例

宏里面参数不加括号容易出错,在使用时尽量加括号 程序1: #include<stdio.h> #define SQARE(X) X*X int main() { int  n = 10; int m=SQARE(n); printf("m=%d\n",m); return 0; } 结果: m=100 请按任意键继续. . . 分析:貌似没有出问题,请看下面两个例子 程序2: #include<stdio.h> #define SQARE(X) X*X int 

RHEL6.5上Oracle ACFS与Linux samba一起使用时遇到的bug

RHEL上的Oracle ACFS与linux samba一起使用时遇到的bug 一.环境介绍: cat /etc/issue的结果为: Red Hat Enterprise Linux Server release 6.5 (Santiago) Kernel \r on an \m GI的详细patch信息:仅仅安装了GI的11.2.0.4版本,没有打任何的GI psu,没有打任何的GI patch 二.问题说明: 这是一套rhel6.5的rac,使用的是Oracle GI集群软件,使用了ac

解决导航、Tabbar、tableview配合使用时,tableview错位的问题

导航.Tabbar.tableview配合使用时,tableview会出现错位的情况,特别是除tabbar的第一个选项的tableview, 解决方法非常简单,如下: self.tabBarController = [[UITabBarController alloc] init]; self.tabBarController.edgesForExtendedLayout = UIRectEdgeNone;//防止tableview错位 _tabBarControllerNav = [[UINa

在使用时的区别是当我们想访问一个对象(object)的元素dollars 和yens

以上两种定义的唯一区别在于左边的定义中我们给了union一个名字price,而在右边的定义中我们没给.在使用时的区别是当我们想访问一个对象(object)的元素dollars 和yens 时,在前一种定义的情况下,需要使用: book.price.dollars book.price.yens 而在后面一种定义下,我们直接使用: book.dollars book.yens 再一次提醒,因为这是一个联合(union),域dollars 和yens 占据的是同一块内存空间,所以它们不能被用来存储两