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 thereadonly
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 parameterparam
is marked as@feed
parameter, an input feed will be expected to process the values associated toparam
.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.