mmap实现进程内写数据和读数据

Posted 爱炒饭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mmap实现进程内写数据和读数据相关的知识,希望对你有一定的参考价值。

使用mmap函数可以实现内存映射,腾讯的mmkv就是基于mmap函数实现的匿名共享内存实现的,android中的binder也用到了mmap函数。本文在同一个进程内(进程和子进程间)实现了一个mmap共享内容的demo。
首先声明一个mmap java工具类BinderHelper.java

//BinderHelper.java
package com.example.mmapapp;

public class BinderHelper 
    // Used to load the 'native-lib' library on application startup.
    static 
        System.loadLibrary("native-lib");
    

    public native String mmapReadFromJNI();
    public native void mmapWriteToJNI();

具体jni代码实现在native-lib.cpp

//native-lib.cpp
#include <jni.h>
#include <string>
#include <fstream>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>


extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_mmapapp_BinderHelper_mmapReadFromJNI(JNIEnv *env, jobject thiz) 
    std::string file = "/sdcard/mybinder";
    int mFd = open(file.c_str(),O_RDWR|O_CREAT,S_IRWXU);
    ftruncate(mFd,4096);//设定文件大小
    int8_t *m_prt = static_cast<int8_t *>(mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, mFd,0));
    char *buf = static_cast<char *>(malloc(100));
    memcpy(buf,m_prt,100);
    std::string result(buf);
    munmap(m_prt,4096);//取消映射
    close(mFd);
    return env->NewStringUTF(result.c_str());


extern "C"
JNIEXPORT void JNICALL
Java_com_example_mmapapp_BinderHelper_mmapWriteToJNI(JNIEnv *env, jobject thiz) 
    std::string file = "/sdcard/mybinder";
    int mFd = open(file.c_str(),O_RDWR|O_CREAT,S_IRWXU);
    ftruncate(mFd,4096);//设定文件大小
    int8_t *m_prt = static_cast<int8_t *>(mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, mFd,0));
    std::string data("data from MainActivity");
    memcpy(m_prt,data.data(),data.size());

主进程在MainActivity.java中使用mmap向内存中写数据,然后跳转到子进程SecondActivity.java

//MainActivity.java
package com.example.mmapapp;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity 

    BinderHelper mBinderHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBinderHelper = new BinderHelper();
        initPermission();
    

    private void initPermission() 
        requestPermissions(new String[]Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,200);
    


    public void write(View view) 
        mBinderHelper.mmapWriteToJNI();
        startActivity(new Intent(MainActivity.this,SecondActivity.class));
    

子进程SecondActivity.java使用相同的路径和mmap函数去读数据并正确显示到界面上

//SecondActivity.java
package com.example.mmapapp;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class SecondActivity extends AppCompatActivity 
    private BinderHelper mBinderHelper;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        mTextView = findViewById(R.id.txt);
        mBinderHelper = new BinderHelper();
        initPermission();
    

    private void initPermission() 
        requestPermissions(new String[]Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,200);
    

    public void read(View view) 
        mTextView.setText(mBinderHelper.mmapReadFromJNI());
    

以上是关于mmap实现进程内写数据和读数据的主要内容,如果未能解决你的问题,请参考以下文章

mmap实现进程内写数据和读数据

Android跨进程通信-mmap函数

linux设备驱动物理内存映射

通过使用 mmap() 在进程之间共享内存

linux共享内存和mmap的区别

Linux之共享内存shm和内存映射mmap