簡體   English   中英

NDK中的共享內存區域

[英]Shared memory region in NDK

我想要一個共享內存塊(一個ashmem區域),該內存塊是從本機代碼映射和訪問的。 我也希望該塊可以被多個應用程序使用。 我也希望它能在SDK級別7(Android 2.1)上運行

有兩條路線。 我可以用本機代碼創建一個ashmem區域。 但是然后的問題是-如何將整數文件描述符傳遞給另一個進程? 您可以通過Parcel FileDescriptor對象,但是無法圍繞原始FD構造對象。 還有ParcelFileDescriptor ,它支持圍繞和檢索整數FD的構造,但是相關方法僅在SDK級別12或更高版本中受支持。

另外,我可以創建一個MemoryFile 有一種在包裹中傳遞它的丑陋方法 但是,如何從文件描述符中檢索文件描述符,以便本機代碼具有mmap()

在從1.5到4.1的所有版本的Android上, FileDescriptor都有一個稱為descriptorint數據成員。 它在較早版本的Android上是私有包,在最近的Android上是私有包。 通過一些故意的訪問控制顛覆,您可以通過反射或JNI進行訪問。 默認情況下,每個用戶都可以繞過訪問控制(如果發生反射,則通過Field.setAccessible() ;如果是JNI,則可以Field.setAccessible()

考慮到這一點,您可以很好地圍繞本機FD構造FileDescriptor 構造一個空白的,然后設置descriptor 這就是構造這些代碼時會執行的零碎工作。

誰知道,這個骯臟的hack最終是否會破裂。 幸運的是,在我看來,這並不是核心功能,而是有些優雅的降級。

如果平台允許,則可以有條件地使用受支持的ParcelFileDescriptor方法,使用字段訪問技巧作為后備方法。 這樣,它將是相對未來的證明。

輔助程序庫libnativehelper.so中有一個用於此jniCreateFileDescriptor() https://android.googlesource.com/platform/libnativehelper/+/jb-dev/include/nativehelper/JNIHelp.h的方法 它基本上執行與先前答案中所述相同的操作,但是您可能會發現此方法更簡潔。

這是我在處理類似問題時的工作方式:

與其使用shmfd = open(SHM_PATH,O_RDWR)創建和獲取文件描述符,我將其替換為

int fd = ashmem_create_region("SharedRegionName", size); 

並使用文件描述符獲取基地址:

int base_address = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

//寫入數據您可以使用返回描述符的本機函數將base_address從本機代碼傳遞到Java代碼。

然后,我創建一個帶有aidl接口的服務,並使用該接口從另一個進程綁定該服務。 從服務中,我已使用ParcelFileDescriptor對象返回到另一個進程。 您可以通過以下方式創建ParcelFileDescriptor:

ParcelFileDescriptor desc = ParcelFileDescriptor.fromFd(fd);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM