Fast DDS入门十、Fast DDS的静态类型(IDL Types)详解

本节详细介绍接口定义语言(IDL)文件定义的数据类型(即Fast DDS的静态类型,与Fast DDS的动态类型区分),以及使用IDL创建数据类型的其他机制。

1、Primitive types

下表显示了Fast DDS Gen支持的基本IDL类型以及它们如何映射到C++11。

IDL

C++11

char

char

octet

uint8_t

short

int16_t

unsigned short

uint16_t

long

int32_t

unsigned long

uint32_t

long long

int64_t

unsigned long long

uint64_t

float

float

double

double

long double

long double

boolean

bool

string

std::string

2、Arrays

Fast DDS Gen支持一维和多维阵列Array。数组始终映射到std::array容器。下表显示了支持的数组类型及其映射。

IDL

C++11

char a[5]

std::array<char,5> a

octet a[5]

std::array<uint8_t,5> a

short a[5]

std::array<int16_t,5> a

unsigned short a[5]

std::array<uint16_t,5> a

long a[5]

std::array<int32_t,5> a

unsigned long a[5]

std::array<uint32_t,5> a

long long a[5]

std::array<int64_t,5> a

unsigned long long a[5]

std::array<uint64_t,5> a

float a[5]

std::array<float,5> a

double a[5]

std::array<double,5> a

3、Sequences

Fast DDS Gen支持映射到std::vector容器的序列。下表表示如何处理IDL和C++11之间的映射。

IDL

C++11

sequence<char>

std::vector<char>

sequence<octet>

std::vector<uint8_t>

sequence<short>

std::vector<int16_t>

sequence<unsigned short>

std::vector<uint16_t>

sequence<long>

std::vector<int32_t>

sequence<unsigned long>

std::vector<uint32_t>

sequence<long long>

std::vector<int64_t>

sequence<unsigned long long>

std::vector<uint64_t>

sequence<float>

std::vector<float>

sequence<double>

std::vector<double>

4、Maps

Fast DDS Gen支持与std::map容器等效的map。类型之间的等价性的处理方式与序列相同。

IDL

C++11

map<char, unsigned long long>

std::map<char, uint64_T>

注意:Maps当前仅支持Primitive类型。

5、Structures

您可以使用一组具有多种类型的成员定义IDL结构。它将被转换为C++类,其中通过IDL定义的结构的成员映射到该类的私有数据成员。此外,还创建了set()和get()成员函数来访问这些私有数据成员。

以下IDL结构体定义:

struct Structure
{
octet octet_value;
long long_value;
string string_value;
};

将转换为:

{
public:
    Structure();
    ~Structure();
    Structure(const Structure &x);
    Structure(Structure &&x);
    Structure& operator=(const Structure &x);
    Structure& operator=(Structure &&x);
     
    void octet_value(uint8_t _octet_value);
    uint8_t octet_value() const;
    uint8_t& octet_value();
    void long_value(int64_t _long_value);
    int64_t long_value() const;
    int64_t& long_value();
    void string_value(const std::string
        &_string_value);
    void string_value(std::string &&_string_value);
    const std::string& string_value() const;
    std::string& string_value();
private:
    uint8_t m_octet_value;
    int64_t m_long_value;
    std::string m_string_value;
};

结构可以继承其他结构,扩展其成员集。

struct ParentStruct
{
octet parent_member;
};
struct ChildStruct : ParentStruct
{
long child_member;
};

在这种情况下,生成的C++代码将是:

class ParentStruct
{
    octet parent_member;
};
class ChildStruct : public ParentStruct
{
    long child_member;
};

6、Unions

在IDL中,联合被定义为具有自己类型的成员序列,以及指定使用哪个成员的判别式。IDL联合类型被映射为C++类,具有访问联合成员和判别式的成员函数。

以下IDL联合体定义:

union Union switch(long)
{
case 1:
octet octet_value;
case 2:
long long_value;
case 3:
string string_value;
};

将转换为:

class Union
{
public:
    Union();
    ~Union();
    Union(const Union &x);
    Union(Union &&x);
    Union& operator=(const Union &x);
    Union& operator=(Union &&x);
 
    void d(int32_t __d);
    int32_t _d() const;
    int32_t& _d();
 
    void octet_value(uint8_t _octet_value);
    uint8_t octet_value() const;
    uint8_t& octet_value();
    void long_value(int64_t _long_value);
    int64_t long_value() const;
    int64_t& long_value();
    void string_value(const std::string
        &_string_value);
    void string_value(std:: string &&_string_value);
    const std::string& string_value() const;
    std::string& string_value();
 
private:
    int32_t m__d;
    uint8_t m_octet_value;
    int64_t m_long_value;
    std::string m_string_value;
};

7、Bitsets(不对应std::bitset,使用难度较大)

位集是一种特殊的结构,它包含一组比特。位集最多可表示64位。每个成员都被定义为位字段,并简化了对位集某一部分的访问。

例如:

bitset MyBitset
{
bitfield<3> a;
bitfield<10> b;
bitfield<12, int> c;
};

MyBitset类型将存储总共25位(3+10+12),并且需要32位内存(存储位集大小的最低primitive type成员累积相加)。

  • 位字段“a”允许我们访问前3位(0..2)。

  • 位字段“b”允许我们访问下一个10位(3..12)。

  • 位字段“c”允许我们访问下一个12位(13..24)。

生成的C++代码类似于:

class MyBitset
{
public:
    void a(char _a);
    char a() const;
    void b(uint16_t _b);
    uint16_t b() const;
    void c(int32_t _c);
    int32_t c() const;
private:
    std::bitset<25> m_bitset;
};

在内部,它存储为std::bitset。对于每个位字段,get()和set()成员函数都使用较小的可能的原始无符号类型来访问它。在位字段“c”的情况下,用户已确定此访问类型将为int,因此生成的代码使用int32_t而不是自动使用uint16_t。

位集可以继承其他位集,扩展其成员集。

bitset ParentBitset
{
bitfield<3> parent_member;
};
bitset ChildBitset : ParentBitset
{
bitfield<10> child_member;
};

在这种情况下,生成的C++代码将是:

class ParentBitset
{
    std::bitset<3> parent_member;
};
class ChildBitset : public ParentBitset
{
    std::bitset<10> child_member;
};

注意,在这种情况下,ChildBitset将有两个std::bitset数据成员,一个属于ParentBitset,另一个属于ChildBitset。

8、Enumerations

IDL格式的枚举类型是具有关联数值的标识符的集合。IDL枚举类型直接映射到相应的C++11枚举定义。

以下为IDL枚举类型:

enum Enumeration
{
RED,
GREEN,
BLUE
};

将转换为:

enum Enumeration : uint32_t
{
    RED,
    GREEN,
    BLUE
};

9、Bitmasks(对应std::bitset)

Bitmask是一种特殊的枚举,用于管理位掩码。它允许根据位掩码的位置定义位掩码。

以下IDL为位掩码类型:

@bit_bound(8)
bitmask MyBitMask
{
@position( 0) flag0,
@position( 1) flag1,
@position( 4) flag4,
@position( 6) flag6,
flag7
};

将转换为:

enum MyBitMask : uint8_t
{
    flag0 = 0x01 << 0,
    flag1 = 0x01 << 1,
    flag4 = 0x01 << 4,
    flag6 = 0x01 << 6,
    flag7 = 0x01 << 7
};

注解bit_bound定义关联枚举的宽度。它必须是介于1和64之间的正数。如果省略,则为32位。对于每个标志,用户可以使用注释位置来定义标志的位置。如果省略,它将从上次定义的标志开始自动递增,从0开始。

10、Data types with a key

带键的数据类型用于定义单个主题上的数据子流。同一主题上具有相同键的数据值表示同一子流中的数据,而同一主题中具有不同键的数据表示不同子流中数据。中间件将这些子流保持分离,但所有子流都将被限制为主题的相同QoS值。如果未提供键成员,则与主题关联的数据集仅限于单个流。

为了使用键控主题,用户应该在结构中定义一些键成员。这是通过在用作键的结构成员之前编写@Key注释来实现的。例如,在以下IDL文件中,id和type字段将是带键数据类型:

struct MyType
{
@Key long id;
@Key string type;
long positionX;
long positionY;
};

Fast DDS Gen自动检测键控标记,并为TopicDataType(getKey())中的键生成函数正确地生成序列化方法,为Key 成员序列化大端字节序的128位MD5摘要。

注意:开源Fast DDS版本当前并未真正实现key的分流,静态类型key定义后,订阅者初始化时无法依据key来订阅,订阅者还是监听并接收到发布者发送的所有key的数据。静态类型对应的动态类型也没有key的分流定义,源码中也没有key分流的处理。在key示例程序实际测试中,也验证了该功能并未真正实现。

11、Aliases(类型别名容易造成混乱,不建议使用)

IDL 4.2允许对以下Primitive类型使用别名:

int8

uint8

int16

uint16

int32

uint32

int64

uint64

12、Annotations(注解)

注解不属于数据类型定义,它是应用程序允许用户定义和使用OMGIDL4.2规范中定义的注解。如果使用-TypeObject参数,则用户注解将传递给TypeObject生成的代码。

@annotation MyAnnotation
{
long value;
string name;
};

此外,以下标准注释是内置的(未实现的注解将识别并传递给TypeObject)。

Annotation

Implemented behavior

@id

[Unimplemented] Assign a 32-bit integer identifier to an element.

@autoid

[Unimplemented] Automatically allocate identifiers to the elements.

@optional

[Unimplemented] Setting an element as optional.

@extensibility

[Unimplemented] Applied to any element which is constructed. Allow specifying how the

element is allowed to evolve.

@final

[Unimplemented] Shortcut for @extensibility(FINAL)

@appendable

[Unimplemented] Shortcut for @extensibility(APPENDABLE)

@mutable

[Unimplemented] Shortcut for @extensibility(MUTABLE)

@position

Setting a position to an element or group of elements. Used by bitmasks.

@value

[Unimplemented] Allow setting a constant value to any element.

@key

Alias for eProsima’s @Key annotation. Indicate that a data member is part of the key

(please refer to Topics, keys and instances for more information).

@must_understand

[Unimplemented] Indicate that the data member must be understood by any application

making use of that piece of data.

@default_literal

[Unimplemented] Allow selecting one member as the default within a collection.

@default

Allow specifying the default value of the annotated element.

@range

[Unimplemented] Allow specifying a range of allowed values for the annotated element.

@min

[Unimplemented] Allow specifying a minimum value for the annotated element.

@max

[Unimplemented] Allow specifying a maximum value for the annotated element.

@unit

[Unimplemented] Allow specifying a unit of measurement for the annotated element.

@bit_bound

Allow setting a size to a bitmasks.

@external

[Unimplemented] Force the annotated element to be placed in a dedicated data space.

@nested

[Unimplemented] Allow indicating that the objects from the type under annotation will

always be nested within another one.

@verbatim

[Unimplemented] Allow injecting some user-provided information into what the compiler

will generate.

@service

[Unimplemented] Allow indicating that an interface is to be treated as a service.

@oneway

[Unimplemented] Allow indicating that an operation is one way only, meaning that

related information flow will go from client to server but not back.

@ami

[Unimplemented] Allow indicating that an interface or an operation is to be made

callable asynchronously.

@non_serialized

The annotated member will be omitted from serialization.

大多数未实现[Unimplemented]的注解都与扩展类型相关。

13、Comments(注释)

这里有两种编写IDL注释的方法:

字符/*开始注释,注释以字符*/结束。

字符//开始一条注释,该注释终止于它们所在行的末尾。

/* MyStruct definition */

struct MyStruc

{

string mymessage; // mymessage data member.

};

有关IDL约定的更多信息,请参阅IDL 4.2规范。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼爱幻想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值