6. IDL interfaces

eProsima FastDDS-Gen tool allows the generation of source code for a RPC over DDS application from an IDL file. The IDL file must contain the operation that can be called on both the client and server sides, and the parameters that can be passed to them. These operations are specified using the concept of interfaces defined in the OMG IDL specification.

The next subsections serves as a guide to how to define your own IDL interface and how to define exceptions for its operations.

6.1. Defining an IDL interface

eProsima Fast DDS-Gen allows the generation of the code required by both the client and the server to use the Fast DDS Request-Reply internal API (see RPC over DDS Request-Reply API overview), given an IDL interface provided by the user. The following subsections will describe how to define an IDL interface for simple asynchronous operations and data streaming.

6.1.1. IDL specification overview

The OMG IDL specification defines interfaces that client and server objects may use, for example, in the context of a Remote Procedure Calls communication (see RPC over DDS).

Each interface represents a set of operations and attributes, and it is constituted by a header and a body:

  • An interface header is defined by the keyword interface, followed by the interface name and an optional inheritance list, in case of being derived from other interfaces.

    For example, a valid interface header is: interface MyInterface : MyBaseInterface, ...

  • The interface body is enclosed in curly braces and contains the interface members. Each member is defined by its type, name and an optional list of parameters.

    • An operation is declared by specifying the return type, which can be any primitive type, any type previously declared by the user in the IDL file or void if the operation does no return a result; the name of the operation and an optional list of parameters, enclosed by parentheses and separated by commas. Each parameter is specified by its type and name, preceded by an attribute that specifies its direction:

      • in indicates that the parameter is used only for input.

      • out indicates that the parameter is used only for output.

      • inout indicates that the parameter can be used for both input and output.

    • An attribute can be declared by specifying the attribute keyword (preceded by the readonly keyword for read-only attributes), followed by a valid type and its name. Declaring an attribute is logically equivalent to declaring a getter and a setter for plain attributes (i.e: mutable attributes), and a getter for read-only attributes.

Interfaces can also be forward declared, for example interface MyInterface;.

6.1.2. Defining data streaming operations

eProsima Fast DDS-Gen allows to generate code for data streaming in each use case described in RPC Data Streaming, using the @feed builtin annotation in operations:

  • Input feeds can be specified by adding @feed before an in parameter, for example: return_type input_feed_operation(@feed in long param);. When a parameter param is marked as @feed parameter, an input feed will be expected to process the values associated to param.

  • Output feeds can be specified by adding @feed before a return type, for example: @feed return_type output_feed_operation(in long param);. When a return type is marked as @feed parameter, an output feed will be expected to process the values associated to result of the operation.

Client-side, Server-side or bidirectional data streamings can be specified by marking with @feed annotations input parameters, return types or both, respectively.

6.1.3. Example

The following example shows how to define an interfaces, addressing the cases described before:

module Example {

    // forward declaration
    interface MyInterface;

    interface MyBaseInterface {

        typedef long my_type;
        typedef long my_return_type;

        // Operation with in, out and inout parameters
        my_return_type my_operation (
                in long param1,
                out string param2,
                inout my_type param3);

        // Operation with no parameters and no return
        void my_void_operation();

        // Operation describing a Server-side data streaming
        @feed my_return_type my_server_streaming_operation(
                in long param);

        // Operation describing a Client-side data streaming
        my_return_type my_client_streaming_operation(
                @feed in long param);

        // Operation describing a Bidirectional data streaming
        @feed my_return_type my_bidirectional_streaming_operation(
                in long param1,
                @feed in long param2);
    };

    interface MyInterface : MyBaseInterface {

        // Read-only attribute
        readonly attribute my_type my_readonly_attr;

        // Plain attribute
        attribute my_type my_plain_attr;

    };

};

Warning

For now, Fast DDS-Gen tool does not support the generation of code for interfaces which contain attributes. Only operations are supported.

6.2. Exceptions

Exceptions are user-defined structures that can be raised by members of an interface. They are declared similarly to struct types; using the exception keyword, followed by the exception name and a body enclosed in curly braces, which can be empty or contain members:

module Example {

    exception MyException {

        long my_exception_member;

    };

    exception MyOtherException {};
};

Note

In case of an exception being raised, user can access to the value of each member. In this case, out / inout parameters and the return result are undefined.

A list of exceptions can be specified in the member declarations of an interface using raises keyword for operations or readonly attributes, and getraises or setraises for plain attributes:

module Example {

    interface MyInterface {

        // Operation that raises an exception
        my_return_type my_operation(in long param1, out string param2, inout myType param3)
            raises (MyException, MyOtherException);

        // Read-only attribute that raises an exception
        readonly attribute my_type my_readonly_attr
            raises (MyException);

        // Plain attribute that raises exceptions
        attribute my_type my_plain_attr
            getraises (MyException)
            setraises (MyException, MyOtherException);

    };
};

Defining exceptions for attributes makes sense because an attribute declaration implicitly represents read and write operations. For read-only attributes, raises keyword is used to specify the exceptions that may be raised when the getter is called. Similarly, getraises and setraises keywords are used in plain attributes to specify the exceptions that may be raised when the getter and setter are called, respectively.

Note

The list of exceptions must be enclosed in parentheses and separated by commas.

Note

All exception specifications are optional. In no one is specified, the operation should not raise any exception.

In case of specifying both getraises and setraises in the same attribute, getraises expression should be declared in first place.

Warning

In addition to the exceptions specified in the interface, other middleware exceptions may be raised.