一、事件包装类与Send()
方法
在骨架侧,服务实现负责通知事件发生。以BrakeEvent
事件包装类为例,其提供了Send()
方法的两个变体用于发送事件数据:
- 第一个变体接受
SampleType
(通常为事件数据类型)的引用。事件数据由服务应用程序开发人员分配并通过引用传递,调用Send()
后调用者数据可能被删除或更改,绑定实现会进行复制。 - 第二个变体接受
ara::com::SampleAllocateePtr<SampleType>
类型参数,此指针类型应表现得像std::unique_ptr<T>
,即只有一方可持有指针,所有者可通过std::move()
显式放弃所有权。
二、Allocate()
方法及作用
事件包装类中的Allocate()
方法返回一个ara::com::SampleAllocateePtr<SampleType>
的智能指针,该指针指向分配的内存,可在其中写入事件数据样本,随后可将其传递给Send()
的第二个变体。其作用在于优化数据复制,例如当事件数据可能非常大时,避免在Send()
的第一个变体中从应用程序进程堆复制数据到消费者可访问内存位置所带来的时间影响。
三、示例代码
示例1
using namespace ara::com;// 对 RadarService 的实现 - RadarServiceSkeleton 的子类
RadarServiceImpl myRadarService;/*** 在发生 BrakeEvent 时调用的处理程序*/
void BrakeEventHandler() {// 让绑定为事件数据分配内存...SampleAllocateePtr<BrakeEvent::SampleType> curSamplePtr =myRadarService.BrakeEvent.Allocate();// 填充事件数据...curSamplePtr->active = true;fillVector(curSamplePtr->objects);// 现在通知消费者事件...myRadarService.BrakeEvent.Send(std::move(curSamplePtr));// 现在通过 curSamplePtr 访问数据将失败 - // 我们已经放弃了所有权!
}
示例2
#include <iostream>
#include <ara/com/some_interface.h>class MySampleType {
public:int value;
};// 假设这是一个服务实现类
class MyServiceImpl {
public:ara::com::SampleAllocateePtr<MySampleType> allocateSample() {return ara::com::SampleAllocateePtr<MySampleType>(new MySampleType());}void sendSample(ara::com::SampleAllocateePtr<MySampleType> samplePtr) {// 模拟发送操作std::cout << "Sending sample with value: " << samplePtr->value << std::endl;}
};int main() {MyServiceImpl service;// 分配样本ara::com::SampleAllocateePtr<MySampleType> sample = service.allocateSample();sample->value = 42;// 发送样本service.sendSample(std::move(sample));// 此时再尝试通过 sample 访问数据将失败if (sample) {std::cout << "This won't be printed as ownership has been transferred." << std::endl;}return 0;
}
在这个示例中,创建了一个自定义的MySampleType
类型,然后在MyServiceImpl
类中展示了如何使用ara::com::SampleAllocateePtr<MySampleType>
进行样本的分配和发送操作。注意,在调用sendSample
并转移所有权后,不能再通过原来的指针访问数据。