2016-04-18 8 views
2

私は、C++アプリケーションでgrpcを使用しています。クライアント側では、リフレクションを使用してメッセージからブール値を反射的に照会する必要があります。protobuf reflectionを使用して、C++でbooleanフィールド記述子を取得する

応答メッセージを以下に示します。残念ながら、私はbool mAPフィールドのフィールド記述子を見ることができません - しかし、私は文字列フィールドのFieldDescriptorsを見ることができます、何が間違っていますか?

ジョン

message Response { 
    // OTP Connection Status 
    enum OTPConnStatus { 
     Disconnected    = 0; 
     Connected     = 1; 
     InvalidCS     = 2; 
     DiscRequest    = 3; 
    } 

    // define the fields 
    RXMessageType mMessageType = 1; 
    bool mAP      = 2; 
    OTPConnStatus mCS1   = 3; 
    OTPConnStatus mCS2   = 4; 
    OTPConnStatus mCS3   = 5; 
    OTPConnStatus mCS4   = 6; 
    string mOTP1     = 7; 
    string mOTP2     = 8; 
    string mOTP3     = 9; 
    string mOTP4     = 10; 
} 
const auto reflection = pMessage->GetReflection(); 
std::vector<const FieldDescriptor*> fields; 
pMessage->GetReflection()->ListFields(*pMessage, &fields); 
const auto fieldIter = std::find_if(fields.cbegin(), fields.cend(), 
    [&lcFieldName](const FieldDescriptor* next) { 
     return boost::iequals(next->name(), lcFieldName); 
    }); 
if (fieldIter != fields.cend()) { 
    std::string result; 
    auto fieldDescriptor = *fieldIter; 
    if (!fieldDescriptor->is_repeated()) { 
     switch (fieldDescriptor->cpp_type()) { 
     case FieldDescriptor::CPPTYPE_INT32: 
      result = std::to_string(reflection->GetInt32 (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_INT64: 
      result = std::to_string(reflection->GetInt64 (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_UINT32: 
      result = std::to_string(reflection->GetUInt32 (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_UINT64: 
      result = std::to_string(reflection->GetUInt64 (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_DOUBLE: 
      result = std::to_string(reflection->GetDouble (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_FLOAT: 
      result = std::to_string(reflection->GetFloat (
       *pMessage, fieldDescriptor)); 
      break; 
     case FieldDescriptor::CPPTYPE_BOOL: 
      result = reflection->GetBool(
       *pMessage, fieldDescriptor) ? 
       "true" : "false"; 
      break; 
     case FieldDescriptor::CPPTYPE_ENUM: 
      result = reflection->GetEnum(
       *pMessage, fieldDescriptor)-> 
        full_name(); 
      break; 
     case FieldDescriptor::CPPTYPE_STRING: 
      result = reflection->GetString(
       *pMessage, fieldDescriptor); 
      break; 
     case FieldDescriptor::CPPTYPE_MESSAGE: 
      //result = reflection->GetMessage(
      // *pMessage, fieldDescriptor); 
      break; 
     } 
    } 
    std::cout << result << std::endl; 
    exit(0); 
} else { 

編集:私は、私は内容を印刷するために使用されるメッセージを印刷するために使用いるProtobufにおける有用性を発見しました。印刷

const auto reflection = pMessage->GetReflection(); 
std::string formatted; 
pb::TextFormat::PrintToString(*pMessage, &formatted); 
std::cout << formatted; 

:ここでの結果です

mMessageType: OneTimePassword 
mOTP1: "TAILNO1" 
mOTP2: "TAILNO2" 
mOTP3: "TAILNO3" 
mOTP4: "TAILNO4" 

または、ブールフィールド問題の「マップ」は、サーバで設定されていることに注意してください。生成されたCAService.pb.hコードを見て、MessageType(現場のフィールド記述子を持っている)をmAPフィールドと比較すると、私のアプローチでエラーが表示されることがあります。

// optional .ca.RXMessageType mMessageType = 1; 
inline void OTPResponse::clear_mmessagetype() { 
    mmessagetype_ = 0; 
} 
inline ::ca::RXMessageType OTPResponse::mmessagetype() const { 
    // @@protoc_insertion_point(field_get:ca.OTPResponse.mMessageType) 
    return static_cast<::ca::RXMessageType>(mmessagetype_); 
} 
inline void OTPResponse::set_mmessagetype(::ca::RXMessageType value) { 

    mmessagetype_ = value; 
    // @@protoc_insertion_point(field_set:ca.OTPResponse.mMessageType) 
} 

// optional bool mAP = 2; 
inline void OTPResponse::clear_map() { 
    map_ = false; 
} 
inline bool OTPResponse::map() const { 
    // @@protoc_insertion_point(field_get:ca.OTPResponse.mAP) 
    return map_; 
} 
inline void OTPResponse::set_map(bool value) { 

    map_ = value; 
    // @@protoc_insertion_point(field_set:ca.OTPResponse.mAP) 
} 
+0

すべてのフィールド名を印刷すると表示されますか?それはいくつかの奇妙な理由のために名前を変更することができますか?名前フィルタで大文字と小文字を区別する等号を使用する理由は何ですか? –

+0

@StefanHaustein ListFieldsの結果は、5つのフィールド記述子を提供します - mMessageTypeと残りの4つの文字列フィールドmOTP1-4の1つです。メンバーは大文字と小文字が区別されます。また、lcFieldNameはキーボードのユーザによって渡されます。 – johnco3

+1

Reflection :: ListFieldsは、設定されているフィールドのみを列挙しています。ブール値フィールドと列挙型フィールドの省略を説明できますか? –

答えて

3

Reflection::ListFields()は、現在設定されているフィールドのみを一覧表示します。すべてのフィールドを繰り返したり、特定のフィールドを検索するには、Descriptorのフィールドアクセスメソッドを使用します。 GetDescriptorを使用すると、メッセージ(またはReflectionオブジェクト)からメッセージ記述子を取得できます。

+0

すべてのコメントをフォローアップしてくれてありがとう! – johnco3

関連する問題