android / ndk

The Android Native Development Kit
1.96k stars 255 forks source link

ASharedMemory C++ wrapper API #820

Open DanAlbert opened 5 years ago

DanAlbert commented 5 years ago

Forked from https://github.com/android-ndk/ndk/issues/476

Possible API:

namespace android::memory  {
    class SharedMemory final {
    public:
        SharedMemory (const std::string& name, size_t size);
        SharedMemory (std::string_view name, size_t size);
        ~SharedMemory();  // Use RAII to release the memory

        size_t getSize ();
        int setProt (int prot)
    };
}
alexcohn commented 5 years ago

If I am not missing something, this is only "server"-side code. For the client side, one does not need name, but only a file descriptor (unwrapped by binder magic from a ParcelFileDescriptor). The client may want to use such wrapper to get the size. Actually, the Service that passess the ParcelFileDescriptor to client must have access to the underlying file descriptor, as well. Or, better still, the wrapper will return ParcelFileDescriptor on demand:

namespace android::memory  {
  jobject SharedMemory::getFd(JNIEnv *env) {
     return env->NewObject(ParcelFileDescriptor_class, ParcelFileDescriptor_constructor, _fd);
  }
}

It would be nice to add mmap into the wrapper, so that the user can also receive the buffer to read or to write (if protection allows the latter). This could have a nice templated interface, for those who want to look at this buffer as std::vector<Something>.

Actually, this wrapper won't be very useful before there is an NDK wrapper for Binder, or some alternative mechanism of sharing the area with other processes. BTW, I don't understand why you want two constructors. What is the advantage of having std::string side by side with const std::string& ?

enh commented 5 years ago

(one of them is std::string_view.)

ylz-at commented 3 years ago

@alexcohn is suggesting to use ParcelFileDescriptor to send fd over binder or something else, but what if I need to let native talks to native? Is there any example to send fd over STREAMS?

server side use something like

ioctl(fd, I_SENDFD, fd_to_send)

client side use something like

ioctl(fd, I_RECVFD, &recvfd)

and the structure for I_SENDFD and I_RECVFD is,

   struct strrecvfd {
       int    fd;       /* new descriptor */
       uid_t  uid;      /* effective user ID of sender */
       gid_t  gid;      /* effective group ID of sender */
       char   fill[8];
   };

I tried to do this with NDK r22, but failed to include <stropts.h> where strrecvfd, I_SENDFD and I_RECVFD is defined.