나만의 작은 도서관

[TIL][C++] 250908 MMO 서버 개발 96일차: 프로토버프 객체 세팅된 모든 값 확인하는 방법 3가지 본문

Today I Learn

[TIL][C++] 250908 MMO 서버 개발 96일차: 프로토버프 객체 세팅된 모든 값 확인하는 방법 3가지

pledge24 2025. 9. 9. 05:10
주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다. 

프로토버프 객체 세팅된 모든 값 확인하는 방법 3가지

  • 작업을 하다 보면 프로토버프 메시지 객체 자체를 전부 확인하고 싶을 때가 있다. 그럴 때마다 일일이 필드값을 체크하기 귀찮아서 대충 필요한 부분만 확인하고 넘어갔는데, 놀랍게도 이미 프로토버프 메서드로 존재했다. 그래서 오늘은 이에 대해 간단히 정리하고자 한다.

 

대표적인 2가지 방법: DebugString(), ShortDebugString()

  • 이 두 방식은 사용 방법이 간단하다. 그냥 메세지 객체 변수의 멤버 함수 방식으로 호출하면 된다. 예시는 아래와 같다.
MyProto msg;
// ... 값 설정
std::cout << msg.DebugString() << std::endl;

 

 

둘의 차이점은?

  • 이 둘의 차이점은 포맷 차이이다. 여러 줄로 확인하고 싶다면 DebugString, 한 줄로 요약된 결과로 확인하고 싶다면 ShortDebugString을 사용하면 된다. 정리하면 아래와 같다.
    • DebugString(): 사람이 읽기 좋은 멀티라인 문자열로 반환. 모든 필드와 값이 출력된다.
    • ShortDebugString(): 한 줄로 요약된 형식으로 문자열 반환

 

좀 더 구체적인 필드 열거를 위한 reflection API 활용

  • 프로토버프에는 reflection API 가 존재한다. 그래서 프로토버프 객체가 존재한다면, 자연스레 reflection API를 사용할 수 있다.
  • 사용 방법은 아래 예시와 같이 Descriptor 객체와 Reflection 객체를 포인터 타입으로 반환받아 사용하면 된다. (덤으로 위 두 방식도 예시에 추가했다.)
// .proto
message Player {
  int32 id = 1;
  string name = 2;
  repeated int32 scores = 3;
  bool online = 4;
}

// .cpp
Player msg;
msg.set_id(101);
msg.set_name("Alice");
msg.add_scores(1200);
msg.add_scores(1350);
msg.set_online(true);

// 1. reflection API 방식
const google::protobuf::Descriptor* desc = msg.GetDescriptor();
const google::protobuf::Reflection* refl = msg.GetReflection();

for(int32 i = 0; i < desc->field_count(); ++i)
{
	const auto* field = desc->field(i);
	
	// 메세지 필드가 repeated인 경우 진입
	if(field->is_repeated())
	{
		int size = refl->FieldSize(msg, field);
		for(int32 j = 0; j < size; ++j)
		{
			cout << field->name() << "[" << j << "] = " << refl->GetRepeatedString(msg, field, j) << endl;
		}
	}
	// 아니면 일반 필드로 간주
	else
	{
		if(refl->HasField(msg, field))
		{
			cout << field->name() << " = " << refl->GetString(msg, field) << endl;
		}
	}
}

// 2. DebugString()
cout << msg.DebugString() << endl;

// 3. ShortDebugString()
cout << msg.ShortDebugString() <<endl;

// =============결과 예시====================

// 1. (reflection API)
id = 101
name = Alice
scores[0] = 1200
scores[1] = 1350
online = 1

// 2. DebugString()
id: 101
name: "Alice"
scores: 1200
scores: 1350
online: true

// 3. ShortDebugString()
id:101 name:"Alice" scores:1200 scores:1350 online:true