I am working with protobuf to create a system which supports a number of different messages, and I am relying on the dynamic messages, factory, and reflection interface. I can get and set all of the different field data types (uint32, int64, ... etc.) except the string type. When I try to use any of the getters or setters for a field with a string data type, my code segfaults. The first chunk of code is the minimal example (sorry it's so long, but the importer, factory, etc. needs to be in place for it to make sense). The second chunk of code is the proto file that I have been using for testing. My question is how do I access the string field to either set or get the data.
#include <vector> #include <string> #include <sstream> #include <dirent.h> #include <stdexcept> #include <iostream> #include <google/protobuf/message.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/io/tokenizer.h> #include <google/protobuf/compiler/parser.h> #include <google/protobuf/descriptor_database.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/arena.h> class errCollector : public google::protobuf::compiler::MultiFileErrorCollector { public: ~errCollector() {}; void AddError(const std::string& filename, int line, int column, const std::string& message) {}; }; google::protobuf::compiler::Importer* createImporter( ); void buildSubMessages(const google::protobuf::Descriptor* desc, google::protobuf::Message* msg, const google::protobuf::Reflection* ref, google::protobuf::DynamicMessageFactory* factory); int main(int argc, char** argv) { // Usage: ProtobufMinimalExample <message type name> std::string msgType(argv[1]); // Error message stream std::ostringstream msgStream; // Create the importer object which holds all of the .proto files. google::protobuf::compiler::Importer* importer = createImporter(); // Create the descriptor pool which holds all of the message descriptors. const google::protobuf::DescriptorPool* pool(importer->pool()); // Create an object to hold the top-level message. google::protobuf::Message* mutableMsg; // Create an object to hold the top-level message descriptor. const google::protobuf::Descriptor* messageDesc; // Create a message to hold the prototype description of the dynamic message const google::protobuf::Message* protoTypeMsg; // Create the message factory. google::protobuf::DynamicMessageFactory* factory( new google::protobuf::DynamicMessageFactory); messageDesc = pool->FindMessageTypeByName(msgType); protoTypeMsg = factory->GetPrototype(messageDesc); mutableMsg = protoTypeMsg->New(); // Get a submessage in the field named "yellow". const google::protobuf::FieldDescriptor* field = messageDesc->FindFieldByName("yellow"); const google::protobuf::Descriptor* subMsgDesc = field->message_type(); const google::protobuf::Message* subProtoTypeMsg = factory->GetPrototype(subMsgDesc); google::protobuf::Message* subMutableMsg = subProtoTypeMsg->New(); const google::protobuf::Reflection* subReflection = (subMutableMsg->GetReflection()); const google::protobuf::Descriptor* subMutableDesc = subMutableMsg->GetDescriptor(); std::string* name = new std::string(); // Segfault //const google::protobuf::FieldDescriptor* subField = subMutableDesc->FindFieldByName("name"); //subReflection->SetString(mutableMsg, subField, "Hello"); //subReflection->GetString(*(mutableMsg), subField); //subReflection->GetStringReference(*(mutableMsg), subField, name); // Works //const google::protobuf::FieldDescriptor* subField = subMutableDesc->FindFieldByName("score"); //subReflection->SetUInt32(mutableMsg, subField, 9); //subReflection->GetUInt32(*(mutableMsg), subField); return 0; } google::protobuf::compiler::Importer* createImporter() { google::protobuf::compiler::DiskSourceTree srcTree; errCollector error; google::protobuf::compiler::Importer* fdProtoImporter(new google::protobuf::compiler::Importer(&srcTree, &error)); const char* protoFilePath = "./proto"; struct dirent* entry; DIR* dp; std::vector<std::string> importProtoFilenames; dp = opendir(protoFilePath); unsigned char isFile = 0x8; while( (entry = readdir(dp)) ) { if(entry->d_type != isFile) continue; importProtoFilenames.push_back(std::string(entry->d_name)); } closedir(dp); srcTree.MapPath("", protoFilePath); for( auto protoFilename : importProtoFilenames ) { if(fdProtoImporter->Import(protoFilename) == NULL) { continue; } } return std::move(fdProtoImporter); } message SSL_Referee { required uint64 packet_timestamp = 1; enum Stage { NORMAL_FIRST_HALF_PRE = 0; NORMAL_FIRST_HALF = 1; NORMAL_HALF_TIME = 2; NORMAL_SECOND_HALF_PRE = 3; NORMAL_SECOND_HALF = 4; EXTRA_TIME_BREAK = 5; EXTRA_FIRST_HALF_PRE = 6; EXTRA_FIRST_HALF = 7; EXTRA_HALF_TIME = 8; EXTRA_SECOND_HALF_PRE = 9; EXTRA_SECOND_HALF = 10; PENALTY_SHOOTOUT_BREAK = 11; PENALTY_SHOOTOUT = 12; POST_GAME = 13; } required Stage stage = 2; optional sint32 stage_time_left = 3; // These are the "fine" states of play on the field. enum Command { // All robots should completely stop moving. HALT = 0; // Robots must keep 50 cm from the ball. STOP = 1; // A prepared kickoff or penalty may now be taken. NORMAL_START = 2; // The ball is dropped and free for either team. FORCE_START = 3; // The yellow team may move into kickoff position. PREPARE_KICKOFF_YELLOW = 4; // The blue team may move into kickoff position. PREPARE_KICKOFF_BLUE = 5; // The yellow team may move into penalty position. PREPARE_PENALTY_YELLOW = 6; // The blue team may move into penalty position. PREPARE_PENALTY_BLUE = 7; // The yellow team may take a direct free kick. DIRECT_FREE_YELLOW = 8; // The blue team may take a direct free kick. DIRECT_FREE_BLUE = 9; // The yellow team may take an indirect free kick. INDIRECT_FREE_YELLOW = 10; // The blue team may take an indirect free kick. INDIRECT_FREE_BLUE = 11; // The yellow team is currently in a timeout. TIMEOUT_YELLOW = 12; // The blue team is currently in a timeout. TIMEOUT_BLUE = 13; // The yellow team just scored a goal. // For information only. // For rules compliance, teams must treat as STOP. GOAL_YELLOW = 14; // The blue team just scored a goal. GOAL_BLUE = 15; } required Command command = 4; // The number of commands issued since startup (mod 2^32). required uint32 command_counter = 5; // The UNIX timestamp when the command was issued, in microseconds. // This value changes only when a new command is issued, not on each packet. required uint64 command_timestamp = 6; // Information about a single team. message TeamInfo { // The team's name (empty string if operator has not typed anything). required string name = 1; // The number of goals scored by the team during normal play and overtime. required uint32 score = 2; // The number of red cards issued to the team since the beginning of the game. required uint32 red_cards = 3; // The amount of time (in microseconds) left on each yellow card issued to the team. // If no yellow cards are issued, this array has no elements. // Otherwise, times are ordered from smallest to largest. repeated uint32 yellow_card_times = 4 [packed=true]; // The total number of yellow cards ever issued to the team. required uint32 yellow_cards = 5; // The number of timeouts this team can still call. // If in a timeout right now, that timeout is excluded. required uint32 timeouts = 6; // The number of microseconds of timeout this team can use. required uint32 timeout_time = 7; // The pattern number of this team's goalie. required uint32 goalie = 8; } // Information about the two teams. required TeamInfo yellow = 7; required TeamInfo blue = 8; } -- You received this message because you are subscribed to the Google Groups "Protocol Buffers" group. To unsubscribe from this group and stop receiving emails from it, send an email to protobuf+unsubscr...@googlegroups.com. To post to this group, send email to protobuf@googlegroups.com. Visit this group at https://groups.google.com/group/protobuf. For more options, visit https://groups.google.com/d/optout.