C++에서 구조체와 JSON 간 변환 기술

현대 C++ 애플리케이션 개발에서는 데이터를 외부 시스템과 주고받는 일이 빈번하게 발생하며, 이 과정에서 직렬화(serialization)와 역직렬화(deserialization)가 핵심적인 역할을 합니다. 특히 JSON은 그 가벼움과 인간 친화적인 형식 덕분에 네트워크 통신 및 설정 파일 등 다양한 분야에서 표준처럼 사용되고 있습니다. 본 문서에서는 C++ 구조체(struct)와 JSON 데이터를 매끄럽게 변환하는 방법을 nlohmann/json 라이브러리를 중심으로 설명합니다.

nlohmann/json 라이브러리 개요

nlohmann/json은 C++11 이상을 지원하는 헤더 전용(header-only) JSON 라이브러리로, 복잡한 의존성 없이 단일 헤더 파일만 포함하면 바로 사용 가능합니다. 객체 지향적이고 직관적인 API를 제공하여 C++ 데이터를 JSON으로, 또는 그 반대로 변환하는 작업을 매우 간소화합니다.

라이브러리 설치 방법

프로젝트에 이 라이브러리를 추가하는 방법은 다음과 같습니다.

  • 패키지 매니저 사용 (예: vcpkg)
vcpkg install nlohmann-json
  • 수동 설치: GitHub 저장소에서 json.hpp 파일을 다운로드하고 프로젝트 경로에 배치한 후 포함합니다.
#include "json.hpp"

기본 구조체와 JSON 변환

간단한 예제로 사람 정보를 담는 User 구조체를 정의해 보겠습니다.

struct User {
    std::string name;
    int id;
    std::string email;
};

이 구조체를 JSON과 상호 변환하기 위해선 특수한 ADL(Argument-Dependent Lookup) 기반 함수인 to_jsonfrom_json을 오버로드해야 합니다.

#include <iostream>
#include <string>
#include "json.hpp"

using json = nlohmann::json;

struct User {
    std::string name;
    int id;
    std::string email;
};

// 직렬화: User → JSON
void to_json(json& j, const User& u) {
    j = json{
        {"name", u.name},
        {"id", u.id},
        {"email", u.email}
    };
}

// 역직렬화: JSON → User
void from_json(const json& j, User& u) {
    u.name = j.value("name", "");
    u.id = j.value("id", 0);
    u.email = j.value("email", "");
}

j.value() 메서드는 존재하지 않는 키에 대해 기본값을 반환하므로 at()보다 안전하게 사용할 수 있습니다.

사용 예시

다음 코드는 위에서 정의한 변환 함수를 활용하는 예입니다.

int main() {
    // 객체 생성
    User user{"Kim Minsoo", 1001, "kim@example.com"};

    // JSON으로 변환
    json j = user;
    std::cout << "JSON 출력: " << j.dump(2) << std::endl;

    // 다시 객체로 복원
    User restored = j.get<User>();
    std::cout << "복원된 이름: " << restored.name << ", ID: " << restored.id << std::endl;

    return 0;
}

중첩된 구조체 처리

구조체 내부에 또 다른 구조체가 포함된 경우에도 동일한 패턴을 재귀적으로 적용할 수 있습니다.

struct Location {
    std::string city;
    std::string zipcode;
};

struct Employee {
    std::string name;
    int age;
    Location location;
};

// 중첩 타입 변환 함수
void to_json(json& j, const Location& loc) {
    j = json{{"city", loc.city}, {"zipcode", loc.zipcode}};
}

void to_json(json& j, const Employee& emp) {
    j = json{
        {"name", emp.name},
        {"age", emp.age},
        {"location", emp.location}
    };
}

void from_json(const json& j, Location& loc) {
    loc.city = j.value("city", "Unknown");
    loc.zipcode = j.value("zipcode", "");
}

void from_json(const json& j, Employee& emp) {
    emp.name = j.value("name", "");
    emp.age = j.value("age", 0);
    emp.location = j.value("location", Location{});
}

중첩된 필드도 자연스럽게 변환되며, get_to()value()를 통해 안전하게 값을 추출할 수 있습니다.

마무리

nlohmann/json 라이브러리는 C++에서 JSON 처리를 매우 직관적이고 유연하게 만들어 줍니다. 구조체에 대한 직렬화/역직렬화 함수를 작성함으로써, 복잡한 데이터도 깔끔하게 JSON과 상호 운용할 수 있습니다. 헤더 전용이라는 장점까지 더해져 소규모 프로젝트부터 대규모 시스템까지 폭넓게 활용 가능합니다.

태그: nlohmann-json C++ JSON Serialization struct serialization C++11

7월 13일 04:08에 게시됨