ashmem学习example篇

前言:

在阅读本文之前,请对binder通信和匿名binder通信有一定的了解!


首先让我们一起看一个ashmem通信的列子:

源码路径如下:

http://download.csdn.net/detail/u010657219/8170435

列子的使用方法:

编译生成SharedBufferServer  ClientW ClientR 先运行SharedBufferServer ,在分别运行ClientW ClientR,从终端打印可以看到操作共享内存的结果!

注意push到系统内部之后更改权限,否则不能执行。


内部定义了三个类,功能分别如下:

class ISharedBuffer: public IInterface   定义binder通信的接口。

class BpSharedBuffer: public BpInterface<ISharedBuffer> 实现代理端的接口

class BnSharedBuffer: public BnInterface<ISharedBuffer>  定义本地端接口,实现binder通信

class SharedBufferService : public BnSharedBuffer实现native的biner通信接口

SharedBufferService的构造函数如下:

	SharedBufferService(){
		
		CircleBuff_Cblk_t cblk;  //主要是实现读写进程的同步管理
		sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer");  //步骤1.创建一块共享内存区域
		if(heap != NULL){
			
			mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE);//步骤2.获取内存区域中的一部分,这里获取的是全部的共享内存区域,
									//后面就可以使用获取的这一部分共享内存块了

			char * data = (char *)mMemory->pointer();      //获取映射的地址
			Mutex lock(Mutex::SHARED,"hidAudioBuffMutex");

			if(data !=NULL){
				
				cblk.freeSize = SHARED_BUFFER_SIZE -sizeof(cblk);
				//cblk.buffLock =new Mutex(Mutex::SHARED,"hidAudioBuffMutex");
				memcpy(&(cblk.buffLock),&lock,sizeof(lock));
				cblk.writeIndex=0;
				cblk.readIndex =0;
				cblk.empty=1;
				cblk.full =0;
				cblk.offset =sizeof(cblk);
				cblk.dataAvailed =0;
				cblk.size	= SHARED_BUFFER_SIZE - cblk.offset;

				memcpy(data ,&cblk, sizeof(cblk)); //最笨的方法,还可以使用c++ replacement new 具体可以参考: http://blog.csdn.net/u010657219/article/details/40209479
			}

		}
		
	}

ClientW.cpp  ClientR.cpp 分别是对共享内存的写/读操作。

下面来看看怎么写共享内存的:

 sp<IBinder> binder = defaultServiceManager()->getService(String16(SHARED_BUFFER));
        if(binder == NULL)
        {
                printf("Failed to get service: %s.\n", SHARED_BUFFER);
                return -1;
        }

        sp<ISharedBuffer> service = interface_cast<ISharedBuffer>(binder);  
        if(service == NULL)
        {
                return -2;
        }

        sp<IMemory> buffer = service->getBuffer();      //步骤三,获取BpMemory ,想想是在什么时候发生映射的?
        if(buffer == NULL)
        {
                return -3;
        }

		CircleBuff_Cblk_t *cblk = (CircleBuff_Cblk_t *)buffer->pointer(); //步骤四:获取映射的首地址
 
		if(cblk == NULL)
        {
        	printf("get the cblk failed!");
            return -4;
        }

        printf("size =%d wIndex =%d rIndex=%d empty=%d full=%d dataAvai=%d free =%d\n",cblk->size \ 
			,cblk->writeIndex,cblk->readIndex,cblk->empty,cblk->full,cblk->dataAvailed,cblk->freeSize);

		int i =0;
		char buf[256];
		
		memset(buf,0,sizeof(buf));

		for(i=0; i<256 ;i++){

			buf[i]=i;
		}

		int n=0 ,writed=0;

		while(1){
			
				writed = WriteData(cblk,buf+n,20);
				if(writed !=20){
					printf("error : write data != 20 !!! please check!\n");
				}
				
				printf("size =%d wIndex =%d rIndex=%d empty=%d full=%d dataAvai=%d free =%d\n",cblk->size \ 
					,cblk->writeIndex,cblk->readIndex,cblk->empty,cblk->full,cblk->dataAvailed,cblk->freeSize);
				

				n+=20;

				if(n>235)
					n=0;

				sleep(1);
		}

ClientR.cpp 跟写一样,只是从共享内存中读出数据.


你可能感兴趣的:(内存,buffer,android应用)