Android native进程间通信实例-binder结合共享内存

  • 2019 年 10 月 3 日
  • 筆記

???android?????????????????????????????kerneldriversstagingandroidashmem.c???????????android?????????????????????

??1. 

???linux???????????????????32????????????????????4G??????????????????????????

?????????????????????????????binder?socket?????android??????????????????????????????????????1001???????addr?????“hello world”???1009???????addr???“hello world”???????????addr???“hello china”??????????????????????????????????????????????????

???????binder???????????????????????????

??

??2.

???????????????

????????????????????????????????????adb shell??????????a??????????b????a???????????b???????????????????????????????????

?????????????

????a?1. ???????????????????????fd?2. ?????????3. ??????????????????4. ?fd??binder???????????

????b?1. ??binder???fd?2. ?fd?????????3. ???????????????????

?????linux?????????????fd??????

??

??3. 

??3.1

??????????????????android.mk????????????????a????mysharememory_a?????

??

#include <fcntl.h>  #include <stdio.h>  #include <string.h>  #include <linux/ashmem.h>  #include <sys/mman.h>  #include <sys/ioctl.h>  #include <stddef.h>  #include <linux/ipc.h>  #include <linux/shm.h>    #include <binder/IServiceManager.h>  #include <binder/IPCThreadState.h>  #include <binder/Parcel.h>  #include <binder/IInterface.h>    #define DEVASHMEM "/dev/ashmem"  #define SHNAME "hellomemory"  #define MAXBUFSIZE 1024  #define TRANSFDCODE 1000  #define WRITEDATACODE 1001    using namespace android;    int  main(int argc, char *argv[])  {      int fd = open(DEVASHMEM, O_RDWR);      if(fd < 0)      {          return -1;      }        int ret = ioctl(fd, ASHMEM_SET_NAME, SHNAME);      if(ret < 0){          close(fd);          return -1;      }        char *get_sh_addr_write = NULL;      ret = ioctl(fd, ASHMEM_SET_SIZE, MAXBUFSIZE);      if(ret < 0){          close(fd);          return -1;      }        get_sh_addr_write = (char*)mmap(NULL, MAXBUFSIZE , PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);      if(NULL == get_sh_addr_write)      {          return -1;      }      sp<IServiceManager> sm = defaultServiceManager();      sp<IBinder> binder = sm->checkService(String16("mybindertag"));      Parcel data, reply;        data.writeDupFileDescriptor(fd);      binder->transact(TRANSFDCODE, data, &reply);        char input_data[MAXBUFSIZE] = {0};      while(1)      {          printf("read share memory buf is %sn", get_sh_addr_write);          printf("please input data to buf :");          scanf("%s", input_data);          getchar();            strcpy(get_sh_addr_write,input_data);          binder->transact(WRITEDATACODE, data, &reply);      }      return ret;  }

??3.2

 ??mysharememory_b?????

??

#include <fcntl.h>  #include <stdio.h>  #include <string.h>  #include <linux/ashmem.h>  #include <sys/mman.h>  #include <sys/ioctl.h>  #include <stddef.h>  #include <linux/ipc.h>  #include <linux/shm.h>    #include <binder/IServiceManager.h>  #include <binder/IPCThreadState.h>  #include <binder/Parcel.h>  #include <binder/IInterface.h>    #define DEVASHMEM "/dev/ashmem"  #define SHNAME "hellomemory"  #define MAXBUFSIZE 1024  #define TRANSFDCODE 1000  #define WRITEDATACODE 1001    using namespace android;    int g_sh_fd = 0;  class MyBinderService : public BBinder{              status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)              {                  int ret;                  char *get_sh_addr_read = NULL;                  int get_sh_size;                    printf("songsong!! **** onTransact ***** code = %d n",code);                  switch(code)                  {                      case TRANSFDCODE:                          g_sh_fd = data.readFileDescriptor();                          break;                        case WRITEDATACODE:                          get_sh_size = ioctl(g_sh_fd, ASHMEM_GET_SIZE,NULL);                          if(get_sh_size > 0)                          {                              get_sh_addr_read = (char*)mmap(NULL, get_sh_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_sh_fd, 0);                          }                          else                          {                              printf("mmap failed %dn", get_sh_size);                              return -1;                          }                          printf("what is in the share memory: %sn", get_sh_addr_read);                          break;                      default:                            break;                  }                  return NO_ERROR;              }  };    int  main(int argc, char *argv[])  {      defaultServiceManager()->addService(String16("mybindertag"), new MyBinderService());        sp<ProcessState> proc(ProcessState::self());      ProcessState::self()->startThreadPool();      IPCThreadState::self()->joinThreadPool();      return 0;  }

 

??3.3

????????????????mysharememory_b?????

??

    int ret;      ret = munmap((void*)get_sh_addr_read, get_sh_size);      if(ret == -1)      {          return -1;      }        ret = close(g_sh_fd);      if(ret == -1)      {          return -1;      }

 

??

 

??3.4 

???????

??

 

 

 ??4. ?????????????????????????????????????????????????????????

??