0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一起看一下CommonAPI C++是怎么使用的吧

冬至子 来源:拖拉机日记 作者:活到一百岁 2023-01-18 16:34 次阅读

我们已经可以基于vsomeip实现SOME/IP应用,并且服务端和客户端之间进行消息的通信,消息的内容称为Payload
但是设想一下,如果当我们需要传递的消息内容是一个比较复杂的数据结构,比如一个结构体,一两个倒也没事,多了以后,Payload的打包、解析和联调都会是件麻烦的事。

这时,我们会想到序列化,比如用Google Protocol Buffer之类的,是不是可以解决问题呢?

对于非AUTOSAR设备之间的通信,是可以解决的,但对于与AUTOSAR设备之间的通信,恐怕就行不通了,因为Payload是需要遵循AUTOSAR规范的,如图:

2.jpg

于是,我们又会想到,如果有人能把序列化这一步也帮我们做好那就更好了,这就是RPC(Remote Procedure Call,远程过程调用)可以做到的事了。

GENIVI的CommonAPI C++是基于vsomeip实现的RPC框架,今天就让我们一起看一下它是怎么用的吧~

搭建CommonAPI的开发环境,有点费劲的,除了依赖于boost和vsomeip,还有CommonAPI和CommonAPI-SomeIP,以及C++代码生成工具,这里就不一一说明了,我已经整理好,放在Github上,关注公众号,回复“演示代码”,可以获得项目链接。

环境OK了以后,我们可以就创建第一个HelloWorld工程了,按照如图所示CommonAPI的工作流程:

2.jpg

其中,FrancaIDL是一种接口描述语言,和编程语言无关。fidl文件是用IDL写的,它描述了服务提供的接口信息,包括类型(比如method、broadcast、attribute等)、参数、返回值。

创建HelloWorld.fidl文件:

package commonapi


interface HelloWorld {
  version {major 1 minor 0}
  method sayHello {
    in {
      String name
    }
    out {
      String message
    }
  }
}

fdepl文件描述了服务的部署信息,包括Service ID、Instance ID、Method ID、Event ID等。

创建HelloWorld.fdepl文件:

import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-SOMEIP_deployment_spec.fdepl"
import "HelloWorld.fidl"


define org.genivi.commonapi.someip.deployment for interface commonapi.HelloWorld {
  SomeIpServiceID = 4660


  method sayHello {
    SomeIpMethodID = 123
  }
}


define org.genivi.commonapi.someip.deployment for provider as MyService {
  instance commonapi.HelloWorld {
    InstanceId = "test"
    SomeIpInstanceID = 22136
  }
}

CommonAPI代码生成工具几乎支持Franca的全部功能。

用准备好的工具生成代码:

commonapi-core-generator-linux-x86_64 -sk ./fidl/HelloWorld.fidl
commonapi-someip-generator-linux-x86_64 ./fidl/HelloWorld.fdepl

在src-gen/v1/commonapi目录里,可以看到如下这些生成的代码文件:

图片

万事俱备,可以开发应用程序咯~

对于服务端,主程序代码如下:

std::shared_ptr

其中,HelloWorldStubImpl是继承于工具生成的HelloWorldStubDefault:

class HelloWorldStubImpl: public v1_0::commonapi::HelloWorldStubDefault {
public:
    HelloWorldStubImpl();
    virtual ~HelloWorldStubImpl();
    virtual void sayHello(const std::shared_ptr;
};

HelloWorldStubImpl实现了sayHello接口,正如fidl定义的,当客户端发送name,回复“Hello name !”:

void HelloWorldStubImpl::sayHello(const std::shared_ptr
{
    std::stringstream messageStream;
    messageStream << "Hello " << _name << "!";
    std::cout << "sayHello('" << _name << "'): '" << messageStream.str() << "'\\n";
    _reply(messageStream.str());
};

对于客户端,主程序如下:

std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get();
std::shared_ptr

客户端不需要实现接口,直接使用工具生成的HelloWorldProxy就可以了。

编译运行的结果如下:

2.jpg

现在再看一下应该选择CommonAPI还是vsomeip呢?用vsomeip的话,依赖的东西少,Payload的打包和解析要自己写,工作量大,自由发挥的空间也大,用CommonAPI的话,依赖的东西多,环境搭建相对复杂,接口可以用IDL描述,这在SOA中非常有用,很多代码由工具生成,基本通信几乎不需要联调,主要的开发工作是实现服务的接口,相当于填充业务逻辑,工作量少,同时可以发挥的空间也小。很多事都是这样吧,获得便利的同时也会损失一些自由,如何选择还是要具体分析。

通过这个示例,我们看到使用RPC通信和上一篇中基于消息的通信是截然不同的编程体验,RPC让客户端可以像调用本地函数一样调用服务端的函数,很显然它们并不在同一个进程中,这是如何做到的呢?

下面,我们结合一张经典的RPC原理框图来看一下客户端的sayHello到底是怎么调到服务端的sayHello的:

2.jpg

1.client调用本地接口sayHello,HelloWorldProxy就是client的stub(桩),负责将sayHello的参数进行打包,组装成一个或者多个网络请求(这些取决于通信协议和序列化方式);

2.client的stub通过socket向server的stub,也叫skeleton(骨架),发送请求;

3.skeleton通过socket接收到请求;

4.请求消息被发送到skeleton,在这里就是HelloWorldStubDefault,负责将收到的请求拆包,取得client发送的参数;

5.HelloWorldStubDefault把参数发给了HelloWorldStubImpl的sayHello。

6.server在HelloWorldStubImpl的sayHello里处理了请求,通过sayHelloReply_t将返回值发给了HelloWorldStubDefault,它负责把返回值进行打包,组装成一个或者多个网络响应;

7.server的skeleton通过socket向client的stub发出响应;

8.stub通过socket接收到响应消息;

9.响应消息被发送到client的stub,也就是HelloWorldProxy,它负责将响应消息进行解析,取得server发送的参数;

10.client通过HelloWorldProxy的sayHello,得到了returnMessage。

至此,client完成了一次RPC调用~

可以看出,在RPC框架中,桩的实现原理是非常关键的,它屏蔽了网络通信的实现,让客户端可以像调用本地接口一样调用服务端提供的接口,而不用关心用的什么通信协议、序列化方式,以及所有的通信细节。

CommonAPI的桩是由代码生成器根据IDL生成的,而在有的RPC框架里,还可以用动态代理的方式得到。

审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • AUTOSAR
    +关注

    关注

    10

    文章

    362

    浏览量

    21605
  • RPC
    RPC
    +关注

    关注

    0

    文章

    111

    浏览量

    11540
  • SOA
    SOA
    +关注

    关注

    1

    文章

    289

    浏览量

    27499
收藏 人收藏

    评论

    相关推荐

    看一下射频电路中的那些无源器件

    今天我们一起来看一下射频电路中的那些无源器件。和数字和低频电路类似,射频电路也分为无源器件和有源器件
    发表于 10-08 16:03 834次阅读
    <b class='flag-5'>看一下</b>射频电路中的那些无源器件

    一起探索C++的世界!

    C++
    YS YYDS
    发布于 :2023年07月07日 19:10:25

    一起探讨一下这个可行?

    电子元器件、打板PCB、一起探讨等等,既可以省钱也可以交到有想法有创意的朋友,供电子DIY爱好者方便DIY。欢迎各位坛友一起讨论一下,尽可能的提出各种问题,待时机成熟时一起DIY几个创
    发表于 05-30 21:26

    一起来讨论

    一起来讨论
    发表于 10-24 10:35

    SPC560Bxx OSAL组件不能与C++一起使用

    'SPC560Bxx OSAL组件RLA'1.0.201704140929不能与C ++一起使用,因为在osal.h和systimer.h中没有关闭extern'C'-block
    发表于 05-17 07:48

    C++软件设计基础考试题库快来复习一下

    本文档的主要内容详细介绍的是C++软件设计基础考试题库快来复习一下
    发表于 09-28 16:36 12次下载

    看一下SMART高速计数向导的应用

    SMART不仅支持利用指令编写高速计数程序的功能,还提供了便捷的高速计数向导功能,只需要简单组态就可以自动生成程序,而且程序未进行加密,生成后可以修改。下面一起来看一下向导如何组态
    的头像 发表于 11-20 15:30 3407次阅读

    一起来看一下蓝牙版本到现在都经历了哪些变化

    随着蓝牙产品,蓝牙BQB认证的持续火热,蓝牙版本也在直的更新换代。蓝牙的威廉希尔官方网站 在飞速的进步,在方便了我们的生活的同时,也让很多生产带有蓝牙设备的厂商获得了收益。 今天微测检测就来带大家看一下蓝牙
    发表于 03-17 15:41 5352次阅读

    今天我们大家一起来探讨一下关于PCBA生产中的问题

    今年这个春节加上疫情在家差不多待了两个月,也思考乐很多问题,今天我汇总了一下,我们大家一起动动聪明的脑袋瓜,让我们一起来思考和总结一下PC
    发表于 03-25 14:23 1222次阅读

    今天我们大家一起来探讨一下关于PCBA生产中的问题

    今年这个春节加上疫情在家差不多待了两个月,也思考乐很多问题,今天我汇总了一下,我们大家一起动动聪明的脑袋瓜,让我们一起来思考和总结一下PC
    发表于 03-27 14:29 868次阅读

    带大家一起体验一下Vivado的ECO流程

    这里带大家一起体验一下Vivado 的ECO流程,以vivado自带的Example Design为例, 直接用TCL命令修改网表,在正常的寄存器路径之间加级LUT。
    的头像 发表于 11-29 11:04 4374次阅读
    带大家<b class='flag-5'>一起</b>体验<b class='flag-5'>一下</b>Vivado的ECO流程

    34种自动控制原理图展示,了解一下

    各类电气控制接线图、电子元件工作原理图,还有可控硅整流电路及负反馈调速装置原理等等,希望对大家的工作有所帮助,一起来了解一下
    的头像 发表于 07-05 11:16 9201次阅读
    34种自动控制原理图展示,了解<b class='flag-5'>一下</b><b class='flag-5'>吧</b>

    将Arduino库与Raspberry Pi Pico C/C++ SDK一起使用

    电子发烧友网站提供《将Arduino库与Raspberry Pi Pico C/C++ SDK一起使用.zip》资料免费下载
    发表于 06-15 14:43 1次下载
    将Arduino库与Raspberry Pi Pico <b class='flag-5'>C</b>/<b class='flag-5'>C++</b> SDK<b class='flag-5'>一起</b>使用

    mpo光纤跳线规格参数你清楚吗?一起来了解一下

    来了解一下。 mpo光纤跳线规格参数: 适用连接器类型 MPO端:MPO或MTP;分支端连接器:FC、LC、SC、ST(客户选择) 光纤类型 单模 多模(PC) 工作波长范围 1250~1650nm
    的头像 发表于 06-28 11:23 1925次阅读
    mpo光纤跳线规格参数你清楚吗?<b class='flag-5'>一起</b>来了解<b class='flag-5'>一下</b><b class='flag-5'>吧</b>

    盘点一下CST电磁仿真软件的求解器

    今天我们一起来盘点一下CST电磁仿真软件那些牛叉的求解器。快来数一下,你用了里面的几种
    的头像 发表于 11-20 10:18 6204次阅读
    盘点<b class='flag-5'>一下</b>CST电磁仿真软件的求解器