proto文件定义

package lm;message Foo{required int32 id = 1;
}message Bar{required int32  id = 1 [default = 12];required string str= 2 [default = "bar::str"];required Foo    foo= 3;
}

下面分析protoc编译生成的:ph.b和pb.cc文件。

初始化

protoc会定义一个全局对象:

struct StaticDescriptorInitializer_lm_2ehelloworld_2eproto {StaticDescriptorInitializer_lm_2ehelloworld_2eproto() {protobuf_AddDesc_lm_2ehelloworld_2eproto();};
} static_descriptor_initializer_lm_2ehelloworld_2eproto_;

其中protobuf_AddDesc_lm_2ehelloworld_2eproto()函数完成了默认值的初始化:


void protobuf_AddDesc_lm_2ehelloworld_2eproto() {static bool already_here = false;...Foo::default_instance_ = new Foo();Bar::_default_str_ =new ::std::string("bar::str", 8); // string默认值存在这里Bar::default_instance_ = new Bar();Foo::default_instance_->InitAsDefaultInstance();Bar::default_instance_->InitAsDefaultInstance();::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_lm_2ehelloworld_2eproto);
}

同时注册了清理函数protobuf_ShutdownFile_lm_2ehelloworld_2eproto

void protobuf_ShutdownFile_lm_2ehelloworld_2eproto() {delete Foo::default_instance_;delete Foo_reflection_;delete Bar::default_instance_;delete Bar_reflection_;delete Bar::_default_str_;
}

构造

默认值的赋值在构造函数里:

Bar::Bar(): ::google::protobuf::Message() {SharedCtor();// @@protoc_insertion_point(constructor:lm.Bar)
}void Bar::SharedCtor() {::google::protobuf::internal::GetEmptyString();_cached_size_ = 0;id_ = 12; // id默认值str_ = const_cast< ::std::string*>(_default_str_); // str默认值foo_ = NULL;::memset(_has_bits_, 0, sizeof(_has_bits_));
}

整数标示符的名称为kXxxFieldNumber

class Bar : public ::google::protobuf::Message {public:static const int kIdFieldNumber  = 1;static const int kStrFieldNumber = 2;static const int kFooFieldNumber = 3;
};

析构

新建的对象在析构函数里删除:

Bar::~Bar() {// @@protoc_insertion_point(destructor:lm.Bar)SharedDtor();
}void Bar::SharedDtor() {if (str_ != _default_str_) {delete str_;}if (this != default_instance_) {delete foo_;}
};

Mutable Pointer

使用mutable_xxx()时,如果没有set过,则new一个新对象出来返回:

inline ::std::string* Bar::mutable_str() {set_has_str();if (str_ == _default_str_) {str_ = new ::std::string(*_default_str_);}return str_;
}inline ::lm::Foo* Bar::mutable_foo() {set_has_foo();if (foo_ == NULL) foo_ = new ::lm::Foo;return foo_;
}

Allocate Value

使用set_allocated_xxx()时,清理掉原来的对象,用新对象赋值:

inline void Bar::set_allocated_str(::std::string* str) {if (str_ != _default_str_) {delete str_;}if (str) {set_has_str();str_ = str;} else {clear_has_str();str_ = const_cast< ::std::string*>(_default_str_);}
}inline void Bar::set_allocated_foo(::lm::Foo* foo) {delete foo_;foo_ = foo;if (foo) {set_has_foo();} else {clear_has_foo();}
}

Clear

Clear()时重设为默认值:


void Bar::Clear() {if (_has_bits_[0 / 32] & 7) {id_ = 12;if (has_str()) {if (str_ != _default_str_) {str_->assign(*_default_str_);}}if (has_foo()) {if (foo_ != NULL) foo_->::lm::Foo::Clear();}}::memset(_has_bits_, 0, sizeof(_has_bits_));mutable_unknown_fields()->Clear();
}

从这里面看出,只是重新赋值,如果是allocated的值,不会清理,所以需要allocate的人自己管理内存。

转载于:https://www.cnblogs.com/nn0p/p/4167607.html

Protobuf, understand the hood相关推荐

  1. Under the hood: MySQL Pool Scanner (MPS)

    Under the hood: MySQL Pool Scanner (MPS) 由 Shlomo Priymak 于 2013年10月22日上午 9:58 发布 Facebook has one o ...

  2. 使用Protobuf文件一键生成Java类

    使用Protobuf文件生成Java类 .proto 文件生成 .java 参考 看了一篇文章:主题是 proto 先生成 desc,然后在用 FreeMarker 模板引擎来做代码自动生成了: .p ...

  3. 简单protobuf

    protobuf的数据类型,有最简单的那种数据类型,就是一个文件中,定义了一个message 可以在一个文件中定义两个message,两个message之间是没有关联的 可以在一个文件中,定义两个me ...

  4. google ProtoBuf开发者指南

    目录 1   概览 1.1   什么是protocol buffer 1.2   他们如何工作 1.3   为什么不用XML? 1.4   听起来像是为我的解决方案,如何开始? 1.5   一点历史 ...

  5. Ubuntu14.04上编译指定版本的protobuf源码操作步骤

    Google Protobuf的介绍可以参考 http://blog.csdn.net/fengbingchun/article/details/49977903 ,这里介绍在Ubuntu14.04上 ...

  6. Windows7上配置Python Protobuf 操作步骤

    1.  按照http://blog.csdn.net/fengbingchun/article/details/8183468 中步骤,首先安装Python 2.7.10: 2.  按照http:// ...

  7. 【C++】Google Protocol Buffer(protobuf)详解(二)

    代码走读:caffe中protobuf的详细使用过程 [一]proto文件,以caffe.proto中BlobShape为例 syntax = "proto2"; //指明prot ...

  8. 【C++】Google Protocol Buffer(protobuf)详解(一)

    1.简介 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准, Protocol Buffers 是一种轻便高效的结构化数据存储格式 ...

  9. protobufjs 命令执行_【原码笔记】-- protobuf.js 与 Long.js

    protobuf.js的结构和webpack的加载之后的结构很相似.这样的模块化组合是个不错的结构方式.1个是适应了不同的加载方式,2个模块直接很独立.webpack的功能更全一点.但如果自己封装js ...

  10. 在网络通讯中应用Protobuf

    Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强:还有一个比较大的优点就是有着很多的语言平台支持.下面讲解一下如何 ...

最新文章

  1. Cesium入门11 - Interactivity - 交互性
  2. Ubuntu建立和删除用户
  3. 致正煎熬的科研人:一个工具让你快速“KO”学术文献!
  4. moreunit_MoreUnit与MoreUnit
  5. android动态开发,android开发实现动态壁纸
  6. 5G高频段频谱规划启动 大国博弈加剧
  7. 数据科学 IPython 笔记本 8.10 自定义颜色条
  8. 拓扑一致体参数化的复杂模型的等几何分析计算重用
  9. pytorch torch.linspace
  10. thinkphp后台_前后端分离决方案|thinkphpvueadmin 后台接口
  11. java println和print_java中的print和println有区别吗
  12. python 中 print 函数用法总结
  13. Pythonic是什么?
  14. 罗技g502鼠标使用感受,以及与g402的对比体验
  15. ERP进销存系统开发源码交付
  16. 青岛市中小学学籍系统服务器,全国各省市中小学学籍网登录入口
  17. oracle Parallel模式-Parallel用法(/*+PARALLEL(n)*/)
  18. 从0到1:开启商业与未来的秘密
  19. 用python写生日快乐说说_祝自己生日快乐的说说
  20. 天才小毒妃 第961章 她不后悔就够了

热门文章

  1. Splash特征描述子
  2. CentOS6.4 X86_64 kvm+PXE备忘
  3. Dev控件发布到服务器上后样式表不显示解决方法
  4. jdk8,lambda表达(简化代码)
  5. 简单使用mybatis(idea中使用)
  6. Java参数传递对象引用传递失效
  7. Git配置信息相关命令
  8. SpringMvc @PathVariable 工作原理
  9. leetcode笔记--7 Find the Difference
  10. 产品经理第一件事-系统背景研究