首页 文章 精选 留言 我的

精选列表

搜索[系统],共10000篇文章
优秀的个人博客,低调大师

Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(5)

下面我们再来看MemoryBase类在Client端的实现,同样,先看它们的类图关系: 这个图中我们可以看出,MemoryBase类在Client端的实现与MemoryHeapBase类在Client端的实现是类似的,这里只要把IMemory类换成IMemoryHeap类以及把BpMemory类换成BpMemoryHeap类就变成是MemoryHeapBase类在Client端的实现了,因此,我们这里只简单分析BpMemory类的实现,前面已经分析过IMemory类的实现了。 BpMemory类实现在frameworks/base/libs/binder/IMemory.cpp文件中,我们先看它的声明: classBpMemory:publicBpInterface<IMemory> { public: BpMemory(constsp<IBinder>&impl); virtual~BpMemory(); virtualsp<IMemoryHeap>getMemory(ssize_t*offset=0,size_t*size=0)const; private: mutablesp<IMemoryHeap>mHeap; mutablessize_tmOffset; mutablesize_tmSize; }; 和MemoryBase类一样,它实现了IMemory类的getMemory成员函数,在它的成员变量中,mHeap的类型为IMemoryHeap,它指向的是一个BpMemoryHeap对象,mOffset表示这个BpMemory对象所要维护的这部分匿名共享内存在整个匿名共享内存块中的起始位置,mSize表示这个BpMemory对象所要维护的这部分匿名共享内存的大小。 下面我们就看一下BpMemory类的成员函数getMemory的实现: sp<IMemoryHeap>BpMemory::getMemory(ssize_t*offset,size_t*size)const { if(mHeap==0){ Parceldata,reply; data.writeInterfaceToken(IMemory::getInterfaceDescriptor()); if(remote()->transact(GET_MEMORY,data,&reply)==NO_ERROR){ sp<IBinder>heap=reply.readStrongBinder(); ssize_to=reply.readInt32(); size_ts=reply.readInt32(); if(heap!=0){ mHeap=interface_cast<IMemoryHeap>(heap); if(mHeap!=0){ mOffset=o; mSize=s; } } } } if(offset)*offset=mOffset; if(size)*size=mSize; returnmHeap; } 如果成员变量mHeap的值为NULL,就表示这个BpMemory对象尚未建立好匿名共享内存,于是,就会通过一个Binder进程间调用去Server端请求匿名共享内存信息,在这些信息中,最重要的就是这个Server端的MemoryHeapBase对象的引用heap了,通过这个引用可以在Client端进程中创建一个BpMemoryHeap远程接口,最后将这个BpMemoryHeap远程接口保存在成员变量mHeap中,同时,从Server端获得的信息还包括这块匿名共享内存在整个匿名共享内存中的偏移位置以及大小。这样,这个BpMemory对象中的匿名共享内存就准备就绪了。 至此,MemoryBase类的实现就分析完了,下面我们将通过一个实例来说明如何使用MemoryBase类在进程间进行内存共享,因为MemoryBase内部使用了MemoryHeapBase类,所以,这个例子同时也可以说明MemoryHeapBase类的使用方法。 3. MemoryHeapBas类e和MemoryBase类的使用示例 在这个例子中,我们将在Android源代码工程的external目录中创建一个ashmem源代码工程,它里面包括两个应用程序,一个是Server端应用程序SharedBufferServer,它提供一段共享内存来给Client端程序使用,一个是Client端应用程序SharedBufferClient,它简单地对Server端提供的共享内存进行读和写的操作。Server端应用程序SharedBufferServer和Client端应用程序SharedBufferClient通过Binder进程间通信机制来交互,因此,我们需要定义自己的Binder对象接口ISharedBuffer。Server端应用程序SharedBufferServer在内部实现了一个服务SharedBufferService,这个服务托管给Service Manager来管理,因此,Client端应用程序SharedBufferClient可以向Service Manager请求这个SharedBufferService服务的一个远接接口,然后就可以通过这个服务来操作Server端提供的这段共享内存了。 这个工程由三个模块组成,第一个模块定义服务接口,它的相关源代码位于external/ashmem/common目录下,第二个模块实现Server端应用程序SharedBufferServer,它的相关源代码位于external/ashmem/server目录下,第三个模块实现Client端应用程序SharedBufferClient,它的相关源代码码位于external/ashmem/client目录下。 首先来看common模块中的服务接口的定义。在external/ashmem/common目录下,有两个源文件ISharedBuffer.h和ISharedBuffer.cpp。源文件ISharedBuffer.h定义了服务的接口: #ifndefISHAREDBUFFER_H_ #defineISHAREDBUFFER_H_ #include<utils/RefBase.h> #include<binder/IInterface.h> #include<binder/Parcel.h> #defineSHARED_BUFFER_SERVICE"shy.luo.SharedBuffer" #defineSHARED_BUFFER_SIZE4 usingnamespaceandroid; classISharedBuffer:publicIInterface { public: DECLARE_META_INTERFACE(SharedBuffer); virtualsp<IMemory>getBuffer()=0; }; classBnSharedBuffer:publicBnInterface<ISharedBuffer> { public: virtualstatus_tonTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags=0); }; #endif 这个文件定义了一个ISharedBuffer接口,里面只有一个成员函数getBuffer,通过这个成员函数,Client端可以从Server端获得一个匿名共享内存,这块匿名共享内存通过我们上面分析的MemoryBase类来维护。这个文件同时也定义了一个必须要在Server端实现的BnSharedBuffer接口,它里面只有一个成员函数onTransact,这个成员函数是用来处理Client端发送过来的请求的。除了定义这两个接口之外,这个文件还定义了两个公共信息,一个是定义常量SHARED_BUFFER_SERVICE,它是Server端提供的内存共享服务的名称,即这个内存共享服务在Service Manager中是以SHARED_BUFFER_SERVICE来作关键字索引的,另外一个是定义常量SHARED_BUFFER_SIZE,它定义了Server端共享的内存块的大小,它的大小设置为4个字节,在这个例子,将把这个共享内存当作一个整型变量来访问。 源代文件ISharedBuffer.cpp文件定义了一个在Client端使用的BpSharedBuffer接口,它是指向运行在Server端的实现了ISharedBuffer接口的内存共享服务的远程接口,同时,在这个文件里面,也实现了BnSharedBuffer类的onTransact成员函数: #defineLOG_TAG"ISharedBuffer" #include<utils/Log.h> #include<binder/MemoryBase.h> #include"ISharedBuffer.h" usingnamespaceandroid; enum { GET_BUFFER=IBinder::FIRST_CALL_TRANSACTION }; classBpSharedBuffer:publicBpInterface<ISharedBuffer> { public: BpSharedBuffer(constsp<IBinder>&impl) :BpInterface<ISharedBuffer>(impl) { } public: sp<IMemory>getBuffer() { Parceldata; data.writeInterfaceToken(ISharedBuffer::getInterfaceDescriptor()); Parcelreply; remote()->transact(GET_BUFFER,data,&reply); sp<IMemory>buffer=interface_cast<IMemory>(reply.readStrongBinder()); returnbuffer; } }; IMPLEMENT_META_INTERFACE(SharedBuffer,"shy.luo.ISharedBuffer"); status_tBnSharedBuffer::onTransact(uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags) { switch(code) { caseGET_BUFFER: { CHECK_INTERFACE(ISharedBuffer,data,reply); sp<IMemory>buffer=getBuffer(); if(buffer!=NULL) { reply->writeStrongBinder(buffer->asBinder()); } returnNO_ERROR; } default: { returnBBinder::onTransact(code,data,reply,flags); } } } 在BpSharedBuffer类的成员函数transact中,向Server端发出了一个请求代码为GET_BUFFER的Binder进程间调用请求,请求Server端返回一个匿名共享内存对象的远程接口IMemory,它实际指向的是一个BpMemory对象,获得了这个对象之后,就将它返回给调用者;在BnSharedBuffer类的成员函数onTransact中,当它接收到从Client端发送过来的代码为GET_BUFFER的Binder进程间调用请求后,便调用其子类的getBuffer成员函数来获一个匿名共享内存对象接口IMemory,它实际指向的是一个MemoryBase对象,获得了这个对象之后,就把它返回给Client端。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966920,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(4)

2.MemoryBase 文章开始时说过,MemoryBase接口是建立在MemoryHeapBase接口的基础上的,它们都可以作为一个Binder对象来在进程间进行数据共享,它们的关系如下所示: MemoryBase类包含了一个成员变量mHeap,它的类型的IMemoryHeap,MemoryBase类所代表的匿名共享内存就是通过这个成员变量来实现的。 与MemoryHeapBase的分析过程一样,我们先来看MemoryBase类在Server端的实现,然后再来看它在Client端的实现。 MemoryBase在Server端实现的类图如下所示: MemoryBase类在Server端的实现与MemoryHeapBase类在Server端的实现是类似的,这里只要把IMemory类换成IMemoryHeap类、把BnMemory类换成BnMemoryHeap类以及MemoryBase类换成MemoryHeapBase类就变成是MemoryHeapBase类在Server端的实现了,因此,我们这里只简单分析IMemory类和MemoryBase类的实现。 IMemory类定义了MemoryBase类所需要实现的接口,这个类定义在frameworks/base/include/binder/IMemory.h文件中: classIMemory:publicIInterface { public: ...... virtualsp<IMemoryHeap>getMemory(ssize_t*offset=0,size_t*size=0)const=0; ...... void*pointer()const; size_tsize()const; ssize_toffset()const; }; 成员函数getMemory用来获取内部的MemoryHeapBase对象的IMemoryHeap接口;成员函数pointer()用来获取内部所维护的匿名共享内存的基地址;成员函数size()用来获取内部所维护的匿名共享内存的大小;成员函数offset()用来获取内部所维护的这部分匿名共享内存在整个匿名共享内存中的偏移量。 IMemory类本身实现了pointer、size和offset三个成员函数,因此,它的子类,即MemoryBase类,只需要实现getMemory成员函数就可以了。IMemory类的实现定义在frameworks/base/libs/binder/IMemory.cpp文件中: void*IMemory::pointer()const{ ssize_toffset; sp<IMemoryHeap>heap=getMemory(&offset); void*constbase=heap!=0?heap->base():MAP_FAILED; if(base==MAP_FAILED) return0; returnstatic_cast<char*>(base)+offset; } size_tIMemory::size()const{ size_tsize; getMemory(NULL,&size); returnsize; } ssize_tIMemory::offset()const{ ssize_toffset; getMemory(&offset); returnoffset; } MemoryBase类声明在frameworks/base/include/binder/MemoryBase.h文件中: classMemoryBase:publicBnMemory { public: MemoryBase(constsp<IMemoryHeap>&heap,ssize_toffset,size_tsize); ...... virtualsp<IMemoryHeap>getMemory(ssize_t*offset,size_t*size)const; ...... private: size_tmSize; ssize_tmOffset; sp<IMemoryHeap>mHeap; }; MemoryBase类实现在frameworks/base/libs/binder/MemoryBase.cpp文件中: MemoryBase::MemoryBase(constsp<IMemoryHeap>&heap, ssize_toffset,size_tsize) :mSize(size),mOffset(offset),mHeap(heap) { } sp<IMemoryHeap>MemoryBase::getMemory(ssize_t*offset,size_t*size)const { if(offset)*offset=mOffset; if(size)*size=mSize; returnmHeap; } 在它的构造函数中,接受三个参数,参数heap指向的是一个MemoryHeapBase对象,真正的匿名共享内存就是由它来维护的,参数offset表示这个MemoryBase对象所要维护的这部分匿名共享内存在整个匿名共享内存块中的起始位置,参数size表示这个MemoryBase对象所要维护的这部分匿名共享内存的大小。 成员函数getMemory的实现很简单,只是简单地返回内部的MemoryHeapBase对象的IMemoryHeap接口,如果传进来的参数offset和size不为NULL,还会把其内部维护的这部分匿名共享内存在整个匿名共享内存块中的偏移位置以及这部分匿名共享内存的大小返回给调用者。 这里我们可以看出,MemoryBase在Server端的实现只是简单地封装了MemoryHeapBase的实现。1 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966918,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册