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.

Reply via email to