google probuf反射原理之源码分析

来源:互联网 发布:向多个gsm模块发数据 编辑:程序博客网 时间:2024/06/05 05:21

比如建立了一个test.proto

生成了 test.pb.h和test.pb.cpp

里面就会有 

// Force AddDescriptors() to be called at static initialization time.struct StaticDescriptorInitializer_test_2eproto {  StaticDescriptorInitializer_test_2eproto() {    protobuf_AddDesc_test_2eproto();  }} static_descriptor_initializer_test_2eproto_;

static_descriptor_initializer_test_2eproto_是个全局函数,会在main函数之前被调用。

最终会调用:

void protobuf_AddDesc_test_2eproto() {  static bool already_here = false;  if (already_here) return;  already_here = true;  GOOGLE_PROTOBUF_VERIFY_VERSION;  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(    "\n\ntest.proto\"\310\001\n\006Person\022\014\n\004name\030\001 \002(\t\022\n\n"    "\002id\030\002 \002(\005\022\r\n\005email\030\003 \001(\t\022\"\n\005phone\030\004 \003(\0132"    "\023.Person.PhoneNumber\032D\n\013PhoneNumber\022\016\n\006n"    "umber\030\001 \002(\t\022%\n\004type\030\002 \001(\0162\021.Person.Phone"    "Type:\004HOME\"+\n\tPhoneType\022\n\n\006MOBILE\020\000\022\010\n\004H"    "OME\020\001\022\010\n\004WORK\020\002", 215);  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(    "test.proto", &protobuf_RegisterTypes);  Person::default_instance_ = new Person();  Person_PhoneNumber::default_instance_ = new Person_PhoneNumber();  Person::default_instance_->InitAsDefaultInstance();  Person_PhoneNumber::default_instance_->InitAsDefaultInstance();  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_test_2eproto);}

这句 
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(    "test.proto", &protobuf_RegisterTypes);
就把当前文件名和
void protobuf_RegisterTypes(const ::std::string&) {  protobuf_AssignDescriptorsOnce();  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(    Person_descriptor_, &Person::default_instance());  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(    Person_PhoneNumber_descriptor_, &Person_PhoneNumber::default_instance());}
注册进全局的MessageFactory里了;

里面的第二个参数是函数指针:

void protobuf_RegisterTypes(const ::std::string&) {  protobuf_AssignDescriptorsOnce();  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(    Person_descriptor_, &Person::default_instance());  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(    Person_PhoneNumber_descriptor_, &Person_PhoneNumber::default_instance());}

这里就把类的descriptor_注册进去了。

再往下面看:

  Person::default_instance_ = new Person();  Person_PhoneNumber::default_instance_ = new Person_PhoneNumber();

这里会有new对象,也就是我们有多少类,protobuf就先帮我们先new出来了。

当然不要忘记删除:

void protobuf_ShutdownFile_test_2eproto() {  delete Person::default_instance_;  delete Person_reflection_;  delete Person_PhoneNumber::default_instance_;  delete Person_PhoneNumber_reflection_;}

这里会删除,而且是把这个函数注册进全局的删除函数里面:

::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_test_2eproto);

这下子就明白了protobuf的反射机制啦。