c – 动态生成protobuf消息并返回指向它的指针
发布时间:2020-12-16 07:20:39 所属栏目:百科 来源:网络整理
导读:首先,我对C不是很有经验,所以也许我在这里监督一些事情. 我正在尝试使用以下代码从.proto文件动态生成protobuf消息: int init_msg(const std::string filename,protobuf::Arena* arena,protobuf::Message** new_msg){ using namespace google::protobuf; us
首先,我对C不是很有经验,所以也许我在这里监督一些事情.
我正在尝试使用以下代码从.proto文件动态生成protobuf消息: int init_msg(const std::string & filename,protobuf::Arena* arena,protobuf::Message** new_msg){ using namespace google::protobuf; using namespace google::protobuf::compiler; DiskSourceTree source_tree; source_tree.MapPath("file",filename); MuFiErCo error_mist; Importer imp(&source_tree,&error_mist); printf("Lade Datei:%s n",filename.c_str()); const FileDescriptor* f_desc = imp.Import("file"); const Descriptor* desc = f_desc->FindMessageTypeByName("TestNachricht"); const Message* new_msg_proto = dmf.GetPrototype(desc); *new_msg = new_msg_proto->New(arena); //Debug cout << (*new_msg)->GetTypeName() << endl; return 0; } int main(int argc,char* argv[]){ protobuf::Arena arena; protobuf::Message *adr2,*adr1; init_msg("schema-1.proto",&arena,&adr1); init_msg("schema-1.proto",&adr2); printf("MSG_Pointer: %p,%pn",adr1,adr2); cout << adr1->GetTypeName() << endl; arena.Reset(); return 0; } 我想如果我使用Arena,新的Message也可以在函数范围之外使用. 这是输出: Lade Datei:schema-1.proto packet.TestNachricht Lade Datei:schema-1.proto packet.TestNachricht MSG_Pointer: 0x1b293b0,0x1b287f0 Speicherzugriffsfehler (Speicherabzug geschrieben) 解决方法
那就是解决方案. 这是一些工作示例代码 #include <string> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <memory> #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/arena.h> using namespace std; using namespace google::protobuf; class MuFiErCo : public compiler::MultiFileErrorCollector { public: void AddError(const string & filename,int line,int column,const string & message){ printf("Err: %sn",message.c_str()); } void AddWarning(const string & filename,const string & message){ printf("Warn: %sn",message.c_str()); } }; compiler::Importer* init_proto_dir(Arena* arena,const std::string &root_dir){ using namespace compiler; static DiskSourceTree source_tree; source_tree.MapPath("",root_dir); static MuFiErCo error_mist; static Importer* imp = Arena::Create<Importer>(arena,&source_tree,&error_mist); return imp; } void init_proto_def(compiler::Importer* imp,const std::string &proto_file){ using namespace compiler; imp->Import(proto_file); return; } Message* init_msg(compiler::Importer* imp,Arena* arena,const std::string &msg_name){ const DescriptorPool* pool = imp->pool(); static DynamicMessageFactory dmf; const Descriptor* desc = pool->FindMessageTypeByName(msg_name); const Message* msg_proto = dmf.GetPrototype(desc); return msg_proto->New(arena); } int set_value(Message* msg,const char* value_name,unsigned long int value){ const Message::Reflection* reflec = msg->GetReflection(); const Descriptor* desc = msg->GetDescriptor(); const FieldDescriptor* fdesc = desc->FindFieldByName(value_name); reflec->SetUInt64(msg,fdesc,value); return 0; } int main(int argc,char* argv[]){ Arena arena; compiler::Importer* imp = init_proto_dir(&arena,""); init_proto_def(imp,"schema-1.proto"); Message* msg = init_msg(imp,"packet.TestNachricht"); set_value(msg,"zahl",23434); cout << msg->DebugString() << endl; return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |