3. SOME/IP服务接口定义与代码生成
任务目标
在SOME/IP开发中,服务接口定义是通信的契约。本案例将完成一个最小可复现的接口定义与代码生成闭环:使用vsomeip提供的接口描述方式,定义一个包含方法调用(Method)和事件通知(Event)的简单服务,并生成对应的服务端与客户端桩代码骨架,验证接口定义与代码生成流程的正确性。
环境与依赖
- 操作系统:Linux(Ubuntu 20.04+)
- 依赖库:libvsomeip-dev(版本≥3.1)
- 代码生成工具:vsomeip的代码生成器需要Python 3.6+,并安装
vsomeip-gen(通常随vsomeip源码包提供)
接口定义(.json文件)
vsomeip使用JSON格式描述服务接口。以下定义了一个服务(Service ID: 0x1234),包含一个方法add(Method ID: 0x0001)和一个事件status(Event ID: 0x8001,Eventgroup: 0x01):
{
"name": "CalculatorService",
"service_id": "0x1234",
"version": "1.0",
"methods": [
{
"name": "add",
"method_id": "0x0001",
"in_params": [
{"name": "a", "type": "int32"},
{"name": "b", "type": "int32"}
],
"out_params": [
{"name": "result", "type": "int32"}
]
}
],
"events": [
{
"name": "status",
"event_id": "0x8001",
"eventgroup_id": "0x01",
"params": [
{"name": "value", "type": "boolean"}
]
}
]
}
代码生成
使用vsomeip-gen工具生成C++桩代码。将上述JSON保存为calculator.json,执行:
vsomeip-gen calculator.json --output-dir ./generated
生成的文件包括:calculator_service.hpp(服务端接口)、calculator_service.cpp(服务端实现骨架)、calculator_client.hpp(客户端代理)、calculator_client.cpp(客户端实现骨架)。
服务端实现(关键代码)
在生成的服务端骨架中,实现add方法逻辑并周期发送status事件。以下为最小可运行的服务端实现:
#include <vsomeip/vsomeip.hpp>
#include "generated/calculator_service.hpp"
class CalculatorServiceImpl : public CalculatorService {
public:
void add(const std::shared_ptr<vsomeip::message>& request,
const std::shared_ptr<vsomeip::message>& response) override {
// 解析请求参数
auto payload = request->get_payload();
int32_t a = payload->get_data()[0] | (payload->get_data()[1] << 8);
int32_t b = payload->get_data()[2] | (payload->get_data()[3] << 8);
int32_t result = a + b;
// 构造响应
std::vector<vsomeip::byte_t> data(4);
data[0] = result & 0xFF;
data[1] = (result >> 8) & 0xFF;
data[2] = (result >> 16) & 0xFF;
data[3] = (result >> 24) & 0xFF;
response->set_payload(std::make_shared<vsomeip::payload>(data));
}
void start() {
// 注册服务并启动
register_service();
std::thread([this]() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(2));
notify_status(true); // 发送事件
}
}).detach();
vsomeip::runtime::get()->start();
}
};
int main() {
auto service = std::make_shared<CalculatorServiceImpl>();
service->start();
return 0;
}
客户端调用(关键代码)
#include <vsomeip/vsomeip.hpp>
#include "generated/calculator_client.hpp"
class CalculatorClientImpl : public CalculatorClient {
public:
void on_status(bool value) override {
std::cout << "收到事件: status=" << value << std::endl;
}
void call_add() {
int32_t result = add(3, 5);
std::cout << "add(3,5) = " << result << std::endl;
}
};
int main() {
auto client = std::make_shared<CalculatorClientImpl>();
client->init();
client->call_add();
std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待事件
return 0;
}
编译与运行
# 编译服务端
g++ -std=c++11 -o server server.cpp generated/calculator_service.cpp -lvsomeip -lpthread
# 编译客户端
g++ -std=c++11 -o client client.cpp generated/calculator_client.cpp -lvsomeip -lpthread
# 终端1:启动服务端
./server
# 终端2:启动客户端
./client
验证方法
- 编译通过:上述编译命令无错误,生成可执行文件。
- 服务注册成功:服务端启动后,终端输出类似
Service 0x1234 registered的日志。 - 方法调用成功:客户端输出
add(3,5) = 8,说明请求-响应链路正常。 - 事件接收成功:客户端在5秒内输出
收到事件: status=1(每2秒一次),说明事件通知链路正常。
若以上输出均符合预期,则接口定义与代码生成流程验证通过。