15.8.3.2. DataReader
以下是一个支持零拷贝的 DataReader 的应用示例,使用了 Fast DDS 库。如代码片段所示,DataReader 中的配置与 DataWriter 类似。请确保不要禁用 DataSharingQosPolicy
。AUTO 类型会在可能的情况下自动启用零拷贝。
// 创建参与者
DomainParticipantQos pqos;
pqos.name("Participant_sub");
DomainParticipant* participant = DomainParticipantFactory::get_instance()->create_participant(0, pqos);
// 注册类型
TypeSupport type(new LoanableHelloWorldPubSubType());
type.register_type(participant);
// 创建订阅者
Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);
// 创建主题
Topic* topic = participant->create_topic(
"LoanableHelloWorldTopic",
type.get_type_name(),
TOPIC_QOS_DEFAULT);
// 创建读取器
DataReaderQos rqos = subscriber->get_default_datareader_qos();
rqos.history().depth = 10;
rqos.reliability().kind = RELIABLE_RELIABILITY_QOS;
rqos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS;
// 必须将 DataSharingQosPolicy 设置为 AUTO(默认)或 ON,以启用零拷贝
rqos.data_sharing().automatic();
DataReader* reader = subscriber->create_datareader(topic, rqos, &datareader_listener);
最后,下面的代码片段实现了 on_data_available()
的 DataReaderListener
回调。该函数中的关键点如下:
- 声明和处理
LoanableSequence
。 - 检查
DataReader::is_sample_valid()
以验证样本未被替换。有关更多信息,请参考DataReader
和DataWriter
历史关联。 - 使用
DataReader::return_loan()
函数向 DataReader 指示应用程序已完成对序列的访问。
void on_data_available(
eprosima::fastdds::dds::DataReader* reader) override
{
// 为数据类型声明 LoanableSequence
FASTDDS_SEQUENCE(DataSeq, LoanableHelloWorld);
DataSeq data;
SampleInfoSeq infos;
// 访问数据样本集合及其对应的 SampleInfo 结构集合
while (RETCODE_OK == reader->take(data, infos))
{
// 遍历 SampleInfo 序列中的每个 LoanableCollection
for (LoanableCollection::size_type i = 0; i < infos.length(); ++i)
{
// 检查数据样本是否包含数据,或仅用于传达实例中的变化
if (infos[i].valid_data)
{
// 打印数据。
const LoanableHelloWorld& sample = data[i];
++samples;
std::cout << "Sample received (count=" << samples
<< ") at address " << &sample
<< (reader->is_sample_valid(&sample,
&infos[i]) ? " is valid" : " was replaced" ) << std::endl
<< " index=" << sample.index() << std::endl
<< " message=" << sample.message().data() << std::endl;
}
}
// 向 DataReader 指示应用程序已完成对之前通过 read 或 take 获取的数据值和 SampleInfo 集合的访问。
reader->return_loan(data, infos);
}
}
此代码展示了如何设置和使用 Fast DDS 库中的零拷贝特性,以及如何正确地管理内存和验证接收到的数据有效性。
内容由零声教学AI助手提供,问题来源于学员提问