Fastdds_ContentFilteredTopicExample_代码剖析4register_type

        在上一次,我们了解了域参与者的创建过程。在这一章我们将了解,域参与者是怎么注册类型的。在DDS(数据分发服务,Data Distribution Service)中,类型支持(TypeSupport)类的主要作用是管理和注册数据类型,使得这些数据类型可以在不同的组件之间安全、高效地传输。TypeSupport::register_type函数的具体功能是将特定的数据类型注册到DDS的领域参与者(DomainParticipant)中,使该数据类型能够被主题(Topic)和数据写入器(DataWriter)等DDS实体使用。

        其实现是这一句代码:

  type_.register_type(participant_);

这个type_的定义如下:

eprosima::fastdds::dds::TypeSupport type_ = eprosima::fastdds::dds::TypeSupport(new HelloWorldPubSubType());

我们先看看TypeSupport的类定义:

        

class TypeSupport : public std::shared_ptr<TopicDataType>

        

TypeSupport接口是一个抽象接口,必须为应用程序使用的每个具体类型进行特化。TypeSupport是DDS数据类型支持的抽象,它封装了与数据类型相关的操作,比如序列化和反序列化。

每个服务的实现都需要提供一种自动生成特定类型类的方法,该方法可以从类型的描述(例如使用OMG IDL映射中的IDL)生成。在可以使用它创建Topic对象之前,必须使用该类型特定类上的register_type操作注册TypeSupport。

其继承自 std::shared_ptr<TopicDataType> 可以将 TypeSupport 对象作为一个智能指针来使用,从而获得 std::shared_ptr 提供的引用计数和内存自动释放等功能。同时他是接受HelloWorldPubSubType()初始化的,而HelloWorldPubSubType与他一样是TopicDataType的子类,意味着TypeSupport 在构建为类的时候,由于接受了HelloWorldPubSubType()内部构建的TopicDataType的指针,可用同时使用->来访问父类TopicDataType的内容,同时他又可以用.来访问类里面的内容。这也是一种组合的实现方式。其实这里public std::shared_ptr<TopicDataType>里面可以不用是父类也可以是其他想要组合的类,在构造函数的时候可以接受一个相同的指针从而达到组合的目的。

        他接受赋值构造与移动构造:

    * @brief Copy Constructor
     *
     * @param type Another instance of TypeSupport
     */
    FASTDDS_EXPORTED_API TypeSupport(
            const TypeSupport& type) noexcept = default;

    /**
     * @brief Move Constructor
     *
     * @param type Another instance of TypeSupport
     */
    FASTDDS_EXPORTED_API TypeSupport(
            TypeSupport&& type) noexcept = default;

        同时他也接受:

    FASTDDS_EXPORTED_API explicit TypeSupport(
            TopicDataType* ptr)
        : std::shared_ptr<TopicDataType>(ptr)
    {
    }

而HelloWorldPubSubType的定义如下

class HelloWorldPubSubType : public eprosima::fastdds::dds::TopicDataType

我们再来看看注册函数的定义:

        

ReturnCode_t TypeSupport::register_type(
        DomainParticipant* participant) const
{
    return participant->register_type(*this, get_type_name());
}

他其实是把自身传递给了域参与者的注册函数,同时获取默认的类型名称,或者可以自己指定类型名

ReturnCode_t TypeSupport::register_type(
        DomainParticipant* participant,
        std::string type_name) const
{
    return participant->register_type(*this, type_name.empty() ? get_type_name() : type_name);
}

转到域参与者后又转到了域参与者的具体实现实体去让他干活。

ReturnCode_t DomainParticipant::register_type(
        TypeSupport type,
        const std::string& type_name)
{
    return impl_->register_type(type, type_name);
}

具体函数如下:

   ReturnCode_t register_type(
            TypeSupport type,
            const std::string& type_name)
    {
        if (type_name.size() <= 0)
        {
            return RETCODE_BAD_PARAMETER;
        }
        TypeSupport t = find_type(type_name);
        if (!t.empty())
        {
            if (t == type)
            {
                return RETCODE_OK;
            }
            return RETCODE_PRECONDITION_NOT_MET;
        }
        std::lock_guard<std::mutex> lock(mtx_types_);
        types_.insert(std::make_pair(type_name, type));
        return RETCODE_OK;
    }

        这段代码的主要功能就是

  • 函数通过调用find_type来检查是否已经有一个同名的数据类型被注册。
  • 如果find_type返回了一个非空的TypeSupport对象,并且与传入的type相同,那么该数据类型已经被注册,函数返回RETCODE_OK
  • 如果find_type返回的TypeSupport对象与传入的type不同,那意味着已经存在一个不同定义但同名的数据类型,在这种情况下,函数返回RETCODE_PRECONDITION_NOT_MET
  • 如果type_name之前没有被注册,函数将继续进行类型的注册。
  • 使用std::lock_guard<std::mutex>锁定互斥量mtx_types_来保证线程安全,以便在多线程环境下安全地修改类型容器types_
  • 更新类型容器types_,将新的类型名称和类型支持对象作为键值对插入到映射中。

至此将方法与函数名注册到types中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值