首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在进程之间将文件描述符传递给Ashmem

如何在进程之间将文件描述符传递给Ashmem
EN

Stack Overflow用户
提问于 2014-03-16 11:46:23
回答 2查看 3.6K关注 0票数 4

我试图将指向ashmem区域的文件描述符从Service (process A)传递到Activity (process B)。在服务中,我将本机文件描述符放入ParcelFileDescriptor,并将其放入一个包中,并通过Messenger发送。然而,当我试图在活动中使用这个文件描述符时,我得到了errno == 9 (EBADF,坏文件号)。

在Service的JNI中创建ashmem区域:

代码语言:javascript
复制
int fd;
int *buff;
JNIEXPORT jint JNICALL Java_com_example_testservice_Test_getTestFD
/* int Test.getTestFD() */
 (JNIEnv * env, jclass jthis) {
    fd = open("/dev/ashmem", O_RDWR); // I couldn't find library with ashmem_create_region
    ioctl(fd, ASHMEM_SET_NAME, "my_mem");
    ioctl(fd, ASHMEM_SET_SIZE, 640*480*12);
    buff = mmap(NULL, 640*480*12, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(buff == MAP_FAILED)
        return -1;
    buff[0] = 4;
    buff[1] = 5;
    buff[2] = 6;
    return fd;
  }

将fd从服务发送到活动:

代码语言:javascript
复制
int nFD = Test.getTestFD();
ParcelFileDescriptor fd;
try {
    fd = ParcelFileDescriptor.fromFd(nFD);
    Message reply = Message.obtain(this, msg.what, nFD, 0);
    Bundle b = new Bundle(1);
    b.putParcelable("fd", fd);
    reply.setData(b);
    if(msg.replyTo == null) { // Activity asks for FD and we reply to it's message
        Log.e("TestService", "Missing replyTo");
    } else {
        try {
            msg.replyTo.send(reply);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
} catch (IOException e1) {
    e1.printStackTrace();
}

在活动中接收fd:

代码语言:javascript
复制
Bundle bundle = msg.getData();
ParcelFileDescriptor fd = bundle.getParcelable("fd");
int nFD = fd.getFd();
Log.d("ClientLib", "Received FD (Parcel): "+String.valueOf(nFD));
Log.d("ClientLib", "Received FD (raw): "+String.valueOf(msg.arg1));
int ret = Interface.SetDataFD(nFD);  // implementation below
if(ret != 0)
    Log.e("ClientLib", "SetDataFD (parcel) failed. Error code: "+String.valueOf(ret));

ret = Interface.SetDataFD(msg.arg1);
if(ret != 0)
    Log.e("ClientLib", "SetDataFD (raw) failed. Error code: "+String.valueOf(ret));

在活动的JNI中处理fd:

代码语言:javascript
复制
int data_fd = -1;
JNIEXPORT
jint JNICALL Java_com_example_clientlib_Interface_SetDataFD
/* int SetDataFD(int fd) */
(JNIEnv * env, jclass jthis, jint fd)
{
    data_fd = fd;
    int * blah = (int*)mmap(NULL, 16, PROT_READ, MAP_SHARED, data_fd, 0);
    if(blah == MAP_FAILED)
        return errno;
    return 0;
}

以下是我在“逻辑猫”中得到的:

代码语言:javascript
复制
D/ClientLib(22104): Received FD (Parcel): 53
D/ClientLib(22104): Received FD (raw): 49
E/ClientLib(22104): SetDataFD (parcel) failed. Error code: 9
E/ClientLib(22104): SetDataFD (raw) failed. Error code: 19

这里怎么了?我甚至不确定这是否是传递文件描述符的问题,我不知道还能检查什么。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-16 12:35:56

不过,它的工作原理是:)。代码中有一些愚蠢的调试器+9,它正确地返回了0。我要留下密码供参考。

票数 0
EN

Stack Overflow用户

发布于 2015-03-04 12:59:06

//我找不到ashmem_create_region**库

这是角质层图书馆的一部分。您可以将其添加到Android.mk文件中,如下所示:

代码语言:javascript
复制
LOCAL_LDLIBS :=  -lcutils
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22436414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档