4. 服务发现与提供
任务说明
本案例实现基于AUTOSAR Adaptive Platform(AP)中ara::com通信中间件的方法调用(Method Call)机制。目标是通过ara::com的服务代理(Proxy)与服务提供(Skeleton)接口,完成客户端到服务端的远程方法调用,并获取返回值。案例聚焦于C++实现、运行时行为与验证路径,不涉及ara::com完整规范的所有细节。
实现方案
采用ara::com标准API风格,定义服务接口(Service Interface),实现Skeleton端(服务提供者)与Proxy端(服务调用者)。方法调用采用请求-响应模式:Proxy调用方法后阻塞等待Skeleton处理并返回结果。为保持案例独立可运行,使用内存中的直接调用模拟通信传输层,不依赖真实网络或操作系统IPC。
代码实现
// service_interface.h
#pragma once
#include <cstdint>
#include <functional>
#include <memory>
namespace ara {
namespace com {
// 方法调用返回值封装
template <typename T>
class MethodResult {
public:
explicit MethodResult(T val) : value_(val), valid_(true) {}
MethodResult() : value_(), valid_(false) {}
bool IsValid() const { return valid_; }
T GetValue() const { return value_; }
private:
T value_;
bool valid_;
};
// 服务接口定义:算术运算服务
class ArithmeticService {
public:
// 方法ID
static constexpr uint32_t kMethodAdd = 1;
static constexpr uint32_t kMethodMultiply = 2;
// 方法签名
using AddHandler = std::function<int32_t(int32_t, int32_t)>;
using MultiplyHandler = std::function<int32_t(int32_t, int32_t)>;
};
} // namespace com
} // namespace ara
// skeleton.h
#pragma once
#include "service_interface.h"
#include <unordered_map>
#include <functional>
namespace ara {
namespace com {
// Skeleton:服务提供端
class ArithmeticSkeleton {
public:
void SetAddHandler(ArithmeticService::AddHandler handler) {
add_handler_ = std::move(handler);
}
void SetMultiplyHandler(ArithmeticService::MultiplyHandler handler) {
multiply_handler_ = std::move(handler);
}
// 处理来自Proxy的调用(模拟通信层分发)
MethodResult<int32_t> Dispatch(uint32_t method_id, int32_t a, int32_t b) {
switch (method_id) {
case ArithmeticService::kMethodAdd:
if (add_handler_) return MethodResult<int32_t>(add_handler_(a, b));
break;
case ArithmeticService::kMethodMultiply:
if (multiply_handler_) return MethodResult<int32_t>(multiply_handler_(a, b));
break;
default:
break;
}
return MethodResult<int32_t>(); // 无效调用
}
private:
ArithmeticService::AddHandler add_handler_;
ArithmeticService::MultiplyHandler multiply_handler_;
};
} // namespace com
} // namespace ara
// proxy.h
#pragma once
#include "service_interface.h"
#include "skeleton.h"
namespace ara {
namespace com {
// Proxy:服务调用端
class ArithmeticProxy {
public:
// 构造时绑定到Skeleton(模拟服务发现与连接)
explicit ArithmeticProxy(ArithmeticSkeleton& skeleton) : skeleton_(skeleton) {}
// 同步方法调用:加法
MethodResult<int32_t> Add(int32_t a, int32_t b) {
return skeleton_.Dispatch(ArithmeticService::kMethodAdd, a, b);
}
// 同步方法调用:乘法
MethodResult<int32_t> Multiply(int32_t a, int32_t b) {
return skeleton_.Dispatch(ArithmeticService::kMethodMultiply, a, b);
}
private:
ArithmeticSkeleton& skeleton_;
};
} // namespace com
} // namespace ara
// main.cpp
#include "proxy.h"
#include <iostream>
int main() {
using namespace ara::com;
// 1. 创建Skeleton并注册处理方法
ArithmeticSkeleton skeleton;
skeleton.SetAddHandler([](int32_t a, int32_t b) {
return a + b;
});
skeleton.SetMultiplyHandler([](int32_t a, int32_t b) {
return a * b;
});
// 2. 创建Proxy并连接到Skeleton
ArithmeticProxy proxy(skeleton);
// 3. 调用方法
auto sum = proxy.Add(15, 27);
auto product = proxy.Multiply(6, 7);
// 4. 输出结果
if (sum.IsValid()) {
std::cout << "Add(15, 27) = " << sum.GetValue() << std::endl;
} else {
std::cout << "Add call failed" << std::endl;
}
if (product.IsValid()) {
std::cout << "Multiply(6, 7) = " << product.GetValue() << std::endl;
} else {
std::cout << "Multiply call failed" << std::endl;
}
return 0;
}
编译与运行
# 编译(C++11或更高版本)
g++ -std=c++11 -o method_call_demo main.cpp
# 运行
./method_call_demo
预期输出
Add(15, 27) = 42
Multiply(6, 7) = 42
验证方法
运行程序后,观察标准输出是否与上述预期一致。若输出正确,则证明:Proxy端通过ara::com风格接口成功调用了Skeleton端注册的方法,并正确获取了返回值。可修改main.cpp中的输入参数或Skeleton中的处理逻辑,重新编译运行,验证方法调用的参数传递与结果返回机制正常工作。