ARACom Proxy Class API 概念
1. Proxy Class 概述
-
生成方式:Proxy Class 是从 AutoSar 元模型的服务接口描述中生成的,ara::com 标准化了其接口,AP 产品供应商的工具链会生成实现该接口的代理实现类。
-
命名空间:ara::com 期望代理相关的工件在命名空间 “proxy” 中,通常包含在从服务定义及其上下文推导出的命名空间层次结构中。
2. Proxy Class API
-
包含了
FindService
、StartFindService
、StopFindService
、Subscribe
、Unsubscribe
、GetSubscriptionState
、SetSubscriptionStateChangeHandler
、UnsetSubscriptionStateChangeHandler
、GetNewSamples
、GetResult
、GetFreeSampleCount
、SetReceiveHandler
、UnsetReceiveHandler
、ResolveInstanceIDs
、Field::Get
、Field::Set
等方法。
3. RadarService Proxy Class Example
-
类结构:
-
RadarServiceProxy
类中有内部类HandleType
,HandleType
中定义了判断两个服务句柄是否相等的运算符==
以及获取实例标识符的方法GetInstanceId
。 -
RadarServiceProxy
类包含多种方法,如StartFindService
(有基于InstanceIdentifier
和InstanceSpecifier
两种重载形式)、StopFindService
、FindService
(同样有两种重载形式),还有构造函数(接受HandleType
类型的句柄参数),以及删除了拷贝构造函数和拷贝赋值运算符。 -
类中还包含了与服务相关的成员,如
BrakeEvent
(事件)、UpdateRate
(字段)、Calibrate
、Adjust
、LogCurrentState
(方法)。
-
4. 构造函数和句柄概念
-
句柄的作用和来源:
-
调用构造函数后可得到与服务通信的 Proxy 实例,句柄必须包含通信管理绑定实现与服务联系所需的寻址信息,而这个寻址信息取决于绑定实现和技术传输层。
-
对于应用程序开发者来说,通过 ara::com 提供的查找服务实例的 API(
FindService
)来获得包含寻址地址的句柄,这样能保证创建的代理是由现有的服务实例支持的。
-
-
设计原因:
-
应用程序开发者在某些情况下可能希望使用连接到同一个服务实例的 Proxy 的不同实例,通过句柄的间接方式可以让开发者决定是使用相同的 Proxy 实例(共享状态)还是新的 Proxy 实例。
-
另外,Proxy 实例不能进行拷贝构造和拷贝赋值,因为 Proxy 实例拥有如 Event/Field 缓存、注册的处理程序和复杂状态等信息,拷贝可能导致资源泄露风险,所以强制通过
HandleType
创建 Proxy 实例是一种深思熟虑的设计策略。
-
5.Proxy Class API 概念的简单代码示例
请注意,这是一个简化示例,实际使用中可能需要根据具体的 ara::com 库和环境进行调整。
#include <iostream>
#include <vector>
// 假设这是 ara::com 和 ara::core 相关的命名空间,实际需要根据真实环境包含头文件
namespace ara {
namespace com {
class InstanceIdentifier;
class FindServiceHandle;
template <typename T>
class ServiceHandleContainer;
class FindServiceHandler;
}
namespace core {
class InstanceSpecifier;
class Result;
}
}
// 模拟事件处理相关的函数签名
using EventReceiveHandler = std::function<void()>;
using SubscriptionStateChangeHandler = std::function<void()>;
// 模拟 Field 相关的类
class Field {
public:
// 模拟获取 Field 值的方法
int Get() {
return value;
}
// 模拟设置 Field 值的方法
void Set(int newValue) {
value = newValue;
}
private:
int value = 0;
};
// 模拟的 Proxy Class
class ProxyClass {
public:
// 模拟查找服务(基于 InstanceIdentifier)
static ara::core::Result<ara::com::FindServiceHandle> StartFindService(
ara::com::FindServiceHandler<ProxyClass::HandleType> handler,
ara::com::InstanceIdentifier instanceId) {
std::cout << "Starting find service with InstanceIdentifier" << std::endl;
// 实际实现中需要按照相应逻辑处理
return ara::core::Result<ara::com::FindServiceHandle>();
}
// 模拟查找服务(基于 InstanceSpecifier)
static ara::core::Result<ara::com::ServiceHandleContainer<ProxyClass::HandleType>> FindService(
ara::core::InstanceSpecifier instanceSpec) {
std::cout << "Finding service with InstanceSpecifier" << std::endl;
// 实际实现中需要按照相应逻辑处理
return ara::core::Result<ara::com::ServiceHandleContainer<ProxyClass::HandleType>>();
}
// 模拟停止查找服务
static void StopFindService(ara::com::FindServiceHandle handle) {
std::cout << "Stopping find service" << std::endl;
}
// 模拟订阅
void Subscribe() {
std::cout << "Subscribing" << std::endl;
}
// 模拟取消订阅
void Unsubscribe() {
std::cout << "Unsubscribing" << std::endl;
}
// 模拟获取订阅状态
int GetSubscriptionState() const {
return subscriptionState;
}
// 模拟设置订阅状态更改处理程序
void SetSubscriptionStateChangeHandler(SubscriptionStateChangeHandler handler) {
subscriptionChangeHandler = handler;
}
// 模拟移除订阅状态更改处理程序
void UnsetSubscriptionStateChangeHandler() {
subscriptionChangeHandler = nullptr;
}
// 模拟从缓冲区获取新样本
template <typename F>
void GetNewSamples(F&& f) {
std::cout << "Getting new samples" << std::endl;
// 可以在实际实现中调用传入的函数 f 处理样本
}
// 模拟获取结果
int GetResult() {
return result;
}
// 模拟获取可用样本计数
int GetFreeSampleCount() const {
return freeSampleCount;
}
// 模拟设置接收处理程序
void SetReceiveHandler(EventReceiveHandler handler) {
receiveHandler = handler;
}
// 模拟移除接收处理程序
void UnsetReceiveHandler() {
receiveHandler = nullptr;
}
// 模拟解析实例 ID
void ResolveInstanceIDs() {
std::cout << "Resolving instance IDs" << std::endl;
}
// 模拟 Field 获取
Field& Field::Get() {
return field;
}
// 模拟 Field 设置
void Field::Set() {
std::cout << "Setting field" << std::endl;
}
private:
// 模拟订阅状态
int subscriptionState = 0;
// 模拟结果
int result = 0;
// 模拟可用样本计数
int freeSampleCount = 0;
// 模拟接收处理程序
EventReceiveHandler receiveHandler;
// 模拟订阅状态更改处理程序
SubscriptionStateChangeHandler subscriptionChangeHandler;
// 模拟 Field
Field field;
// 模拟句柄类型
class HandleType {
};
};
int main() {
// 使用示例
ProxyClass proxy;
// 查找服务
auto serviceResult = ProxyClass::FindService(ara::core::InstanceSpecifier());
// 启动查找服务
ProxyClass::StartFindService([](auto, auto) {}, ara::com::InstanceIdentifier());
// 停止查找服务
ProxyClass::StopFindService(ara::com::FindServiceHandle());
// 订阅
proxy.Subscribe();
// 设置订阅状态更改处理程序
proxy.SetSubscriptionStateChangeHandler([]() {
std::cout << "Subscription state changed" << std::endl;
});
// 获取新样本
proxy.GetNewSamples([](int sample) {
std::cout << "Processing sample: " << sample << std::endl;
});
// 获取结果
int result = proxy.GetResult();
// 获取可用样本计数
int freeSampleCount = proxy.GetFreeSampleCount();
// 设置接收处理程序
proxy.SetReceiveHandler([]() {
std::cout << "Received event" << std::endl;
});
// 解析实例 ID
proxy.ResolveInstanceIDs();
// 获取 Field 并设置值
auto& field = proxy.Field::Get();
field.Set(10);
return 0;
}
在上述代码中:
ProxyClass
类模拟了文档中提到的 Proxy Class,包含了多个 API 方法的模拟实现,如FindService
、StartFindService
、StopFindService
等。Field
类模拟了与 Field 相关的操作。- 在
main
函数中展示了这些 API 方法的基本使用方式,包括查找服务、启动和停止查找服务、订阅、设置和移除处理程序、获取样本和结果等操作。