Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(6)
2011-11-07 00:58
645 查看
接下来,我们再来看看server模块的实现。在external/ashmem/common目录下,只有一个源文件SharedBufferServer.cpp,它实现了内存共享服务SharedBufferService:
#define LOG_TAG "SharedBufferServer"
#include <utils/Log.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "../common/ISharedBuffer.h"
class SharedBufferService : public BnSharedBuffer
{
public:
SharedBufferService()
{
sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer");
if(heap != NULL)
{
mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE);
int32_t* data = (int32_t*)mMemory->pointer();
if(data != NULL)
{
*data = 0;
}
}
}
virtual ~SharedBufferService()
{
mMemory = NULL;
}
public:
static void instantiate()
{
defaultServiceManager()->addService(String16(SHARED_BUFFER_SERVICE), new SharedBufferService());
}
virtual sp<IMemory> getBuffer()
{
return mMemory;
}
private:
sp<MemoryBase> mMemory;
};
int main(int argc, char** argv)
{
SharedBufferService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
SharedBufferService服务实现了BnSharedBuffer接口。在它的构造函数里面,首先是使用MemoryHeapBase类创建了一个匿名共享内存,大小为SHARED_BUFFER_SIZE。接着,又以这个MemoryHeapBase对象为参数,创建一个MemoryBase对象,这个MemoryBase对象指定要维护的匿名共享内存的的偏移位置为0,大小为SHARED_BUFFER_SIZE,并且,将这个匿名共享内存当作一个整型变量地址,将它初始化为0。最终,这个匿名共享内存对象保存在SharedBufferService类的成员变量mMemory中,这个匿名共享内存对象可以通过成员函数getBuffer来获得。
在Server端应用程序的入口函数main中,首先是调用SharedBufferService静态成员函数instantiate函数来创建一个SharedBufferService实例,然后通过defaultServiceManager函数来获得系统中的Service Manager接口,最后通过这个Service Manager接口的addService函数来把这个SharedBufferService服务添加到Service Manager中去,这样,Client端就可以通过Service Manager来获得这个共享内存服务了。有关Service Manager的实现,请参考前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路,而用来获取Service Manager接口的defaultServiceManager函数的实现可以参考另外一篇文章浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路。初始化好这个共享内存服务之后,程序就通过ProcessState::self()->startThreadPool()函数来创建一个线程等待Client端来请求服务了,最后,程序的主线程也通过IPCThreadState::self()->joinThreadPool()函数来进入到等待Client端来请求服务的状态中。
我们还需要为这个Server端应用程序编译一个编译脚本,在external/ashmem/server目录下,新建一个Android.mk文件,它的内容如下所示:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := ../common/ISharedBuffer.cpp \
SharedBufferServer.cpp
LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder
LOCAL_MODULE := SharedBufferServer
include $(BUILD_EXECUTABLE)
最后,我们再来看看client模块的实现。在external/ashmem/client目录下,只有一个源文件SharedBufferClient.cpp,它的内容如下所示:
#define LOG_TAG "SharedBufferClient"
#include <utils/Log.h>
#include <binder/MemoryBase.h>
#include <binder/IServiceManager.h>
#include "../common/ISharedBuffer.h"
int main()
{
sp<IBinder> binder = defaultServiceManager()->getService(String16(SHARED_BUFFER_SERVICE));
if(binder == NULL)
{
printf("Failed to get service: %s.\n", SHARED_BUFFER_SERVICE);
return -1;
}
sp<ISharedBuffer> service = ISharedBuffer::asInterface(binder);
if(service == NULL)
{
return -2;
}
sp<IMemory> buffer = service->getBuffer();
if(buffer == NULL)
{
return -3;
}
int32_t* data = (int32_t*)buffer->pointer();
if(data == NULL)
{
return -4;
}
printf("The value of the shared buffer is %d.\n", *data);
*data = *data + 1;
printf("Add value 1 to the shared buffer.\n");
return 0;
}
在这个文件中,主要就是定义了Client端应用程序的入口函数main,在这个main函数里面,首先通过Service Manager接口获得前面所实现的匿名共享内存服务SharedBufferService的远程接口service,然后通过这个远程接口的getBuffer成员函数获得由Server端提供的一块匿名共享内存接口buffer,最后通过这个匿名共享内存接口获得这个匿名共享内存的基地址data。有了这个匿名共享内存的地址data之后,我们就可以对它进行读写了,先是把这个匿名共享内存当作是一个整型变量地址进行访问,并输出它的值的大小,然后对这个整量变量进行加1的操作,并写回到原来的共享内存空间中去。这样,当Server端应用程序运行之后,第一次运行这个Client端应用程序时,输出的值为0,第二次运行这个个Client端应用程序时,输出的值为1,第三次运行这个个Client端应用程序时,输出的值为3......依次类推,后面我们将在模拟器中对这个分析进行验证,如果验证成功的话,就说明这个匿名共享内存成功地在Server端和Client端实现共享了。
#define LOG_TAG "SharedBufferServer"
#include <utils/Log.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include "../common/ISharedBuffer.h"
class SharedBufferService : public BnSharedBuffer
{
public:
SharedBufferService()
{
sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer");
if(heap != NULL)
{
mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE);
int32_t* data = (int32_t*)mMemory->pointer();
if(data != NULL)
{
*data = 0;
}
}
}
virtual ~SharedBufferService()
{
mMemory = NULL;
}
public:
static void instantiate()
{
defaultServiceManager()->addService(String16(SHARED_BUFFER_SERVICE), new SharedBufferService());
}
virtual sp<IMemory> getBuffer()
{
return mMemory;
}
private:
sp<MemoryBase> mMemory;
};
int main(int argc, char** argv)
{
SharedBufferService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
return 0;
}
SharedBufferService服务实现了BnSharedBuffer接口。在它的构造函数里面,首先是使用MemoryHeapBase类创建了一个匿名共享内存,大小为SHARED_BUFFER_SIZE。接着,又以这个MemoryHeapBase对象为参数,创建一个MemoryBase对象,这个MemoryBase对象指定要维护的匿名共享内存的的偏移位置为0,大小为SHARED_BUFFER_SIZE,并且,将这个匿名共享内存当作一个整型变量地址,将它初始化为0。最终,这个匿名共享内存对象保存在SharedBufferService类的成员变量mMemory中,这个匿名共享内存对象可以通过成员函数getBuffer来获得。
在Server端应用程序的入口函数main中,首先是调用SharedBufferService静态成员函数instantiate函数来创建一个SharedBufferService实例,然后通过defaultServiceManager函数来获得系统中的Service Manager接口,最后通过这个Service Manager接口的addService函数来把这个SharedBufferService服务添加到Service Manager中去,这样,Client端就可以通过Service Manager来获得这个共享内存服务了。有关Service Manager的实现,请参考前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路,而用来获取Service Manager接口的defaultServiceManager函数的实现可以参考另外一篇文章浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路。初始化好这个共享内存服务之后,程序就通过ProcessState::self()->startThreadPool()函数来创建一个线程等待Client端来请求服务了,最后,程序的主线程也通过IPCThreadState::self()->joinThreadPool()函数来进入到等待Client端来请求服务的状态中。
我们还需要为这个Server端应用程序编译一个编译脚本,在external/ashmem/server目录下,新建一个Android.mk文件,它的内容如下所示:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := ../common/ISharedBuffer.cpp \
SharedBufferServer.cpp
LOCAL_SHARED_LIBRARIES:= libcutils libutils libbinder
LOCAL_MODULE := SharedBufferServer
include $(BUILD_EXECUTABLE)
最后,我们再来看看client模块的实现。在external/ashmem/client目录下,只有一个源文件SharedBufferClient.cpp,它的内容如下所示:
#define LOG_TAG "SharedBufferClient"
#include <utils/Log.h>
#include <binder/MemoryBase.h>
#include <binder/IServiceManager.h>
#include "../common/ISharedBuffer.h"
int main()
{
sp<IBinder> binder = defaultServiceManager()->getService(String16(SHARED_BUFFER_SERVICE));
if(binder == NULL)
{
printf("Failed to get service: %s.\n", SHARED_BUFFER_SERVICE);
return -1;
}
sp<ISharedBuffer> service = ISharedBuffer::asInterface(binder);
if(service == NULL)
{
return -2;
}
sp<IMemory> buffer = service->getBuffer();
if(buffer == NULL)
{
return -3;
}
int32_t* data = (int32_t*)buffer->pointer();
if(data == NULL)
{
return -4;
}
printf("The value of the shared buffer is %d.\n", *data);
*data = *data + 1;
printf("Add value 1 to the shared buffer.\n");
return 0;
}
在这个文件中,主要就是定义了Client端应用程序的入口函数main,在这个main函数里面,首先通过Service Manager接口获得前面所实现的匿名共享内存服务SharedBufferService的远程接口service,然后通过这个远程接口的getBuffer成员函数获得由Server端提供的一块匿名共享内存接口buffer,最后通过这个匿名共享内存接口获得这个匿名共享内存的基地址data。有了这个匿名共享内存的地址data之后,我们就可以对它进行读写了,先是把这个匿名共享内存当作是一个整型变量地址进行访问,并输出它的值的大小,然后对这个整量变量进行加1的操作,并写回到原来的共享内存空间中去。这样,当Server端应用程序运行之后,第一次运行这个Client端应用程序时,输出的值为0,第二次运行这个个Client端应用程序时,输出的值为1,第三次运行这个个Client端应用程序时,输出的值为3......依次类推,后面我们将在模拟器中对这个分析进行验证,如果验证成功的话,就说明这个匿名共享内存成功地在Server端和Client端实现共享了。
相关文章推荐
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(1)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(2)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(3)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(4)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(5)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析(7)
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)Java调用接口分析
- Android系统匿名共享内存(Anonymous Shared Memory)Java调用接口分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析