web-dev-qa-db-ja.com

protobuf enumを文字列として取得する方法は?

C++でprotobuf列挙型に相当する文字列を取得することは可能ですか?

例えば。:

メッセージの説明は次のとおりです:

package MyPackage;

message MyMessage
{
    enum RequestType
    {
        Login = 0;
        Logout = 1;
    }

    optional RequestType requestType = 1;
}

私のコードでは、次のようなことをしたい:

MyMessage::RequestType requestType = MyMessage::RequestType::Login;

// requestTypeString will be "Login"
std::string requestTypeString = ProtobufEnumToString(requestType);
24

EnumDescriptor および EnumValueDescriptor クラスは、この種の操作に使用でき、生成された.pb.hおよび.pb.cc名前は読みやすいので、名前を調べて、提供する機能の詳細を取得できます。

この特定のケースでは、以下が動作するはずです(テストされていません):

std::string requestTypeString = MyMessage_RequestType_Name(requestType);
23
Josh Kelley

Josh Kelley の回答を参照し、 EnumDescriptor および EnumValueDescriptor を使用します。

EnumDescriptorのドキュメントには次のように書かれています。

  • EnumDescriptorを取得するには

    生成された列挙型のEnumDescriptorを取得するには、TypeName_descriptor()を呼び出します。 DescriptorPoolを使用して、独自の記述子を作成します。

  • 文字列値を取得するには、FindValueByNumber(int number)を使用します

    const EnumValueDescriptor * EnumDescriptor :: FindValueByNumber(int number)const

    数値で値を検索します。

    そのような値が存在しない場合はNULLを返します。複数の値にこの数がある場合、最初に定義されたものが返されます。

例、protobuf列挙型を取得します。

enum UserStatus {
  AWAY = 0;
  ONLINE = 1;
  OFFLINE = 2;
}

値から文字列名を読み取り、文字列名から値を読み取るコード:

const google::protobuf::EnumDescriptor *descriptor = UserStatus_descriptor();

std::string name = descriptor->FindValueByNumber(UserStatus::ONLINE)->name();
int number = descriptor->FindValueByName("ONLINE")->number();

std::cout << "Enum name: " << name << std::endl;
std::cout << "Enum number: " << number << std::endl;
8
rmldts