RTI Connext 모던 C++ DDS API의 주요 개선 사항
모던 C++ API for DDS를 도입한 이후 고객들로부터 상당한 관심을 보았습니다. 많은 고객이 C++11을 사용하여 새로운 시스템을 구축하기 시작했고, 우리는 여러 영향력 있는 개선 사항으로 API를 지속적으로 개선해 왔습니다.
모던 C++로 향상된 IDL 매핑
RTI의 코드 생성기는 이제 -stl 옵션을 제공하며, -language C++03 또는 -language C++11과 함께 사용됩니다. 이 옵션은 여러 IDL 타입의 매핑을 업데이트합니다:
- 언바운드 시퀀스 →
std::vector (-unboundedSupport 필요)
- 바운드 시퀀스 →
rti::core::bounded_sequence<T, Bound>. 이 타입은 std::vector처럼 동작하지만 역직렬화에 최적화되어 있습니다. 더 낮은 지연 시간 시나리오에서는 @use_vector 어노테이션을 사용하여 std::vector를 선호할 수 있습니다.
- 문자열 및 와이드 문자열 타입 →
std::string 및 std::wstring
@external 어노테이션이 달린 멤버('*' 포인터 표기)는 dds::core::external<T>가 되며, shared_ptr과 유사한 더 안전한 래퍼입니다. 이는 미들웨어가 메모리를 대여할 때(예: LoanedSamples 컨테이너에서 읽기) 외부 멤버가 덮어써지는 것을 방지합니다.
예를 들어, 다음 IDL 타입이 주어졌을 때:
struct MyType { sequence<long> my_unbounded_seq; sequence<long, 10> my_bounded_seq; @use_vector sequence<long, 10> my_other_bounded_seq string my_str; @external long my_external; };
명령 rtiddsgen -language C++11 -stl -unboundedSupport MyType.idl을 사용하면 생성된 C++11 클래스는 다음과 같습니다:
class MyType { public: MyType(); ... MyType (MyType&&) = default; MyType& operator=(MyType&&) = default; MyType& operator=(const MyType&) = default; MyType(const MyType&) = default; std::vector<int32_t>& my_unbounded_seq() noexcept; const std::vector<int32_t>& my_unbounded_seq() const noexcept; void my_unbounded_seq(const std::vector<int32_t>& value); rti::core::bounded_sequence<int32_t, 10>& my_bounded_seq() noexcept; const rti::core::bounded_sequence<int32_t, 10>& my_bounded_seq() const noexcept; void my_bounded_seq(const rti::core::bounded_sequence<int32_t, 10>& value); std::vector<int32_t>& my_other_bounded_seq() noexcept; const std::vector<int32_t>& my_other_bounded_seq() const noexcept; void my_other_bounded_seq(const std::vector<int32_t>& value); std::string& my_str() noexcept; const std::string& my_str() const noexcept; void my_str(const std::string& value); dds::core::external<int32_t>& my_external() noexcept; const dds::core::external<int32_t>& my_external() const noexcept; void my_external(dds::core::external<int32_t> value); ... };
모던 C++용 요청-응답 API
API에는 이제 두 개의 새로운 엔티티가 포함됩니다: rti::request::Requester 및 rti::request::Replier. 이들은 네이티브 요청-응답 패턴을 제공하며, 이는 다른 언어에서 이미 사용 가능했고 5.3에서 프로토타입으로 도입되었으며 5.3.0.7에서 프로덕션 준비가 되었습니다.
간결한 코드 예제는 여기에서 확인할 수 있습니다.
소소한 API 개선 사항
몇 가지 일반적인 작업을 단순화했습니다:
WaitSet의 조건 핸들러가 이제 조건을 인수로 받아들일 수 있어 인수 없는 펑터가 필요 없습니다:
condition.handler([]() { // do something }); // 또는 새로운 시그니처로 condition.handler([](dds::core::cond::Condition c) { // do something (condition == c) });
주문형 과거 데이터를 위한 TopicQuery
5.3에 도입된 TopicQuery는 애플리케이션이 과거 데이터를 주문형으로 검색할 수 있게 합니다. 모던 C++ API에서 DataReader로부터 TopicQuery를 다음과 같이 생성할 수 있습니다:
rti::sub::TopicQuery my_topic_query( my_reader, rti::sub::TopicQuerySelection(dds::topic::Filter("x < 10")) );
그런 다음 라이브 데이터를 정상적으로 수신하면서 필터와 일치하는 과거 샘플을 가져올 수 있습니다.
앞으로의 전망
C++17이 승인되고 C++20이 다가옴에 따라 RTI Connext는 모던 언어 기능과 성능 개선으로 C++ API를 계속 진화시킬 것입니다. RTI 블로그를 구독하거나 최신 업데이트를 위해 계속 지켜봐 주세요.