Skip to the main content.

Did you know?

 

RTI is the world’s largest DDS supplier and Connext is the most trusted software framework for critical systems.

Tiered-Support-Plan-DatasheetTiered Support Plans

Our Professional Services team brings extensive experience to train, problem-solve, mentor, and accelerate customer success.

Learn more

Developers

From downloads to Hello World, we've got you covered. Find all of the tutorials, documentation, peer conversations and inspiration you need to get started using Connext today.

Try the Connectivity Selection Tool ⇢

Resources

RTI provides a broad range of technical and high-level resources designed to assist in understanding industry applications, the RTI Connext product line and its underlying data-centric technology.

Company

RTI is the largest software framework company for autonomous systems. The company’s RTI Connext product enables intelligent architecture by sharing information in real time, making large applications work together as one.

News & Events
Cooperation

2 min read

What’s New in the Modern C++ API

What’s New in the Modern C++ API

Since we introduced the modern C++ API for DDS, we’ve seen a lot of interest from our customers. Several of them have started developing brand new systems in C++11. We’ve also been constantly improving the API and there are a few new features, big and small, that I wanted to talk about here.

Improved IDL mapping to C++. The Code Generator provides a new, enhanced mapping to modern C++. A new option, -stl, combined with -language C++03 or -language C++11 enables it.

This option changes the mapping of the following IDL types:

  • Unbounded sequences map tostd::vector(this requires -unboundedSupport)
  • Bounded sequences map torti::core::bounded_sequence<T, Bound>. This type is similar to a std::vector, but is optimized for data deserialization. If minimizing latency is not a top concern, or T is simple, you can choose to map bounded sequences to std::vector as well with the new @use_vector IDL annotation.
  • Strings and wide strings map tostd::string,andstd::wstringrespectively.
  • Members with the new annotation @external (equivalent to the “*” pointer notation) map to the new typedds::core::external<T>,similar toshared_ptr.This wrapper provides a safer alternative to the previous mapping to a raw pointer. An external member cannot be overwritten when its memory is loaned from the middleware (for example, when reading aLoanedSamplescontainer).

For example, given the following IDL type:

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;
};

This is how the generated C++11 type looks like with “-stl”

(Full command: rtiddsgen -language C++11 -stl -unboundedSupport MyType.idl)

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);

   ...
};

Request-reply API. The new request-reply API for modern C++ extends the DDS API with two entities: rti::request::Requester and rti::request::Replier. This API was already available in other languages, and is now available in modern C++ as a prototype in 5.3 and production-ready in 5.3.0.7.

A simple code example is availabe here

We’ve made additional small improvements to make the API easier to use. For instance, we simplified how to use handlers for dispatching Conditions in a WaitSet. Previously, handlers had to be no-argument functors. Now they can take the Condition as an argument.

condition.handler([]() { 
// do something
});

// now we also support
condition.handler([](dds::core::cond::Condition c) {
// do something (condition == c)
});

We’ve also kept the API up to date with new connectivity features, such as TopicQuery, which we introduced in 5.3. Topic queries provide a scalable mechanism for applications to receive historical data on-demand.
In the modern C++ API you can create a TopicQuery instance from a DataReader as follows:

rti::sub::TopicQuery my_topic_query(
my_reader,
rti::sub::TopicQuerySelection(dds::topic::Filter("x < 10")));

Now you can use my_reader to take the historical data samples from all matching DataWriters that pass the filter. You can also keep reading “live” data as usual.

With C++17 just approved and C++20 around the corner, we are continuing to update and modernize our C++ API with exciting features. Stay tuned or simply subscribe to the RTI Blog for all of the latest updates!