0
protobufを使用して動的作成メッセージに関する奇妙な問題を抱えています。コードは以下のように、エラーなく動作します。しかし、私は次のように主な機能をコメントアウトする場合:protobufコアダンプ機能で動的生成メッセージをラップする場合
それはコア!主に異なるのは、関数内のメッセージの作成のみをラップしているようです。呼び出しスタックを検索するとき:
(gdb) where
#0 0x0000000001436ed0 in ??()
#1 0x00007ff218c8f0e3 in google::protobuf::internal::ReflectionOps::Clear (message=0x1437aa0)
at google/protobuf/reflection_ops.cc:133
#2 0x00007ff218c3328b in InlineParseFromCodedStream (message=0x1437aa0, input=0x7ffc82fc3aa0)
at google/protobuf/message_lite.cc:131
#3 InlineParseFromArray (message=0x1437aa0, size=<optimized out>, data=<optimized out>)
at google/protobuf/message_lite.cc:143
#4 google::protobuf::MessageLite::ParseFromArray (this=0x1437aa0, data=<optimized out>,
size=<optimized out>) at google/protobuf/message_lite.cc:207
#5 0x000000000040137e in parse_msg (p_msg=0x1437aa0,
buf=0x7ffc82fc3dc0 "\b\237\215\006\022\024QT-SIM-504761089-101", len=26) at pb_test.cpp:46
#6 0x000000000040172d in main (argc=1, argv=0x7ffc82fc42c8) at pb_test.cpp:95
(gdb) fr 1
#1 0x00007ff218c8f0e3 in google::protobuf::internal::ReflectionOps::Clear (message=0x1437aa0)
at google/protobuf/reflection_ops.cc:133
133 reflection->ListFields(*message, &fields);
(gdb) p reflection->ListFields
Cannot take address of method ListFields.
ListFieldsはNull(純粋仮想関数呼び出し)のようです。誰が私になぜこれが起こるのかを知る手伝いをすることができますか?関数で作成をラップするときにコードが機能しないのはなぜですか?前もって感謝します!ファイルtest.protoで
:
message SvrRegRsp{
required int32 RetCode = 1;
required string SID = 2;
}
のcppファイル:factory.GetPrototype(desc);
とmessage->New();
の
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/compiler/importer.h>
using namespace google::protobuf;
using namespace google::protobuf::compiler;
enum {
MAX_PACKET_LEN = 1024,
};
int gen_msg(Importer* pb, char* buf, int* len)
{
const Descriptor* desc = pb->pool()->FindMessageTypeByName("SvrRegRsp");
DynamicMessageFactory factory;
const Message *message = factory.GetPrototype(desc);
Message *p_msg = message->New();
const Reflection *reflection = p_msg->GetReflection();
const FieldDescriptor *field = desc->field(1);
reflection->SetString(p_msg, field, "QT-SIM-504761089-101");
field = desc->field(0);
reflection->SetInt32(p_msg, field, 99999);
p_msg->SerializeToArray(buf, *len) ;
*len = p_msg->ByteSize();
std::string s = p_msg->DebugString();
printf("req: %s\nsize: %d\n", s.c_str(), *len);
return 0;
}
int parse_msg(Message* p_msg, const char* buf, int len)
{
if(p_msg) {
p_msg->ParseFromArray(buf, len); // core here, because p_msg vptr is NULL.
std::string s = p_msg->DebugString();
printf("rsp2:\n%s\nsize: %d\n", s.c_str(), len);
}
return 0;
}
Message* get_msg(Importer* pb)
{
const Descriptor* desc = pb->pool()->FindMessageTypeByName("SvrRegRsp");
DynamicMessageFactory factory;
const Message *message = factory.GetPrototype(desc);
Message *p_msg = message->New();
return p_msg;
}
int main(int argc, char** argv)
{
char cwd[256] = {0};
getcwd(cwd, sizeof(cwd));
printf("cwd: %s\n", cwd);
DiskSourceTree disk;
disk.MapPath("", cwd);
Importer pb(&disk, NULL);
const FileDescriptor* file_desc = pb.Import("test.proto");
if(!file_desc) {
return -1;
}
char packet[MAX_PACKET_LEN] = {0};
int len = MAX_PACKET_LEN;
gen_msg(&pb, packet, &len);
//#if 0
const Descriptor* desc = pb.pool()->FindMessageTypeByName("SvrRegRsp");
DynamicMessageFactory factory;
const Message *message = factory.GetPrototype(desc);
Message *p_msg = message->New();
//#endif
// Message* p_msg = get_msg(&pb);
parse_msg(p_msg, packet, len);
return 0;
}
はい、「DynamicMessageFactory」は、それと共に作成されたすべてのメッセージよりも長く存続する必要があります。 –