2. Protocol Buffers Extension Components

Protocol Buffers Extension consists of two RTI plugins for protoc and a set of DDS-specific options for Protocol Buffers types.

2.1. IDL4 Converter Plugin

The Protocol Buffers Extension IDL4 Converter Plugin (idl4) converts .proto files into equivalent .idl files using the --idl4_out protoc option. For example:

protoc --idl4_out=<outputdir> message.proto
  • Example input (message.proto):

    syntax = "proto3";
    
    import "other.proto";
    
    package myapp;
    
    message MyMessage {
        int32 foo = 1;
        Other bar = 2;
    }
    
  • Example output (message.idl):

    #ifndef myapp_message_proto_IDL4_
    #define myapp_message_proto_IDL4_
    
    #include "other.idl"
    
    module myapp {
        @mutable
        struct MyMessage {
            @id(1) int32 foo;
            @id(2) @optional Other bar;
        };
    }; // module myapp
    
    #endif // myapp_message_proto_IDL4_
    

See Protocol Buffers to DDS-XTYPES Mapping for a detailed description of the mapping between Protocol Buffers and IDL4 types.

2.2. C++ Code Generator Plugin

RTI Code Generator (rtiddsgen) includes the Connext C++ Code Generator Plugin (connext-cpp) to generate C++ source code from IDL files. This plugin works together with the Protocol Buffers built-in C++ code generator to create C++ classes for each data type in a .proto file. For example:

protoc --cpp_out=<outputdir> \
        --connext-cpp_out=<outputdir> \
        message.proto

Example output (message.pb.h, abridged):

#include "other.pb.h"

// Injected by RTI code generator
#include "rti/topic/cdr/ProtobufInterpreter.hpp"

namespace myapp {

class MyMessage final : public ::google::protobuf::Message {
public:
    MyMessage();
    ~MyMessage() override;

    bool has_foo() const;
    void clear_foo();
    int32_t foo() const;

    bool has_bar() const;
    void clear_bar();
    const ::myapp::Other& bar() const;
    ::myapp::Other* mutable_bar();
    void set_allocated_bar(::myapp::Other* bar);

    // Injected by RTI code generator
    template <typename MessageType>
    friend struct ::rti::topic::interpreter::detail::protobuf_message_access;

private:
    int32_t foo_;
    ::myapp::Other* bar_;
}

} // namespace myapp

2.3. DDS Options for Protocol Buffers

Custom options are available to control IDL4 types derived from Protocol Buffers definitions. These DDS-specific options are defined using Protocol Buffers syntax and become available after importing RTI’s supporting omg/dds/descriptor.proto file.

  • Example input (message.proto, annotated):

    syntax = "proto3";
    
    import "other.proto";
    
    import "omg/dds/descriptor.proto";
    
    package myapp;
    
    message MyMessage {
        option (.omg.dds.type) = {
            default_id: DDS_DEFAULT_ID,
            auto_id: HASH
        };
    
        int32 foo = 1 [ (.omg.dds.member).key = true ];
        Other bar = 2 [ (.omg.dds.member) = {
          optional: true,
          hash_id: "baz"
        }];
    }
    
  • Example output (message.idl, customized):

    #ifndef myapp_message_proto_IDL4_
    #define myapp_message_proto_IDL4_
    
    #include "other.idl"
    
    module myapp {
        @mutable
        @autoid(hash)
        struct MyMessage {
            @key int32 foo;
            @hash_id("baz") Other bar;
        };
    }; // module myapp
    
    #endif // myapp_message_proto_IDL4_
    

See DDS Options for Protocol Buffers for detailed information about the RTI descriptor file.

2.4. Accessing the RTI Plugins

The Protocol Buffers plugins, idl4 and connext-cpp, are located in <NDDSHOME>/bin. To make them accessible to protoc, add this directory to your PATH environment variable. For example:

export PATH=<NDDSHOME>/bin:$PATH

Alternatively, specify the explicit path of each plugin using the protoc command:

protoc --plugin=<NDDSHOME>/bin/protoc-gen-idl4 \
       --plugin=<NDDSHOME>/bin/protoc-gen-connext-cpp \
       ...

2.5. Limitations

The current versions of the RTI plugins for protoc have the following known limitations:

2.5.1. Platforms and compatibility

The RTI plugins are included in the installer for Linux and macOS. While these are the primary platforms where the plugins are installed, RTI has also tested the generated code’s compatibility with QNX 8 builds. The generated code is expected to be compatible with Windows; however, this platform has not yet been formally tested by RTI.

2.5.2. Recursive types

The IDL4 Converter Plugin does not support recursive types, such as a message that contains a field of its own type.