android jni C/C++ 层和java层 进程间共享数据

android jni C/C++ 层和java层 进程间共享数据,

原理利用 linux 文件的特性,访问同一文件名的句柄,然后再此基础上,

mmap数据空间。非常简单,粗暴的处理方式,此方法不需要向进程间传递fd句柄

当然如果一定要传,方法是:  将句柄往java层送,利用java封装的函数打包句柄,

然后用blind 传送,进程B也利用java层接口 解出句柄,不是简单传进程A的fd,那是无效的。

进程A:

   内存,可以随意定义,双方协商的文件名 “/data/test.mem”

U64 fd = open(ASHMEM_DEVICE, O_RDWR);

    if(fd < 0){ return -1; }

addr = (char*)mmap(NULL, size , PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

shm_id = fd;

句柄打包

ParcelFileDescriptor cfd = ParcelFileDescriptor.fromFd(fd);

FileDescriptor fileDescriptor2 = cfd.getFileDescriptor();

data.writeFileDescriptor(fileDescriptor2);

mBinder.transact(0, data, reply, 0);

进程B

ParcelFileDescriptor pfd = reply.readParcelable(null);

// 或者

ParcelFileDescriptor pfd = reply.readFileDescriptor();

方法1,取出句柄

shm_id = fd;

方法2,打开同文件,不需要同一句柄

U64 fd = open(ASHMEM_DEVICE, O_RDWR);

    if(fd < 0){ return -1; }

addr = (char*)mmap(NULL, size , PROT_READ | PROT_WRITE, MAP_SHARED,shm_id , 0);

   msync(p, s->length, MS_SYNC);  // ------ 注意修改数据方,一定要 同步数据

需要注意的:

    这种简单的方法, 共享内存的大小,跟这个 文件大小相关,这个是测试中发现的,所以

你需要创建一个临时文件,数据随便写,关键是大小。虽然很多网上分析说,跟这个不相关,但

实测是相关的。

#include <jni.h>
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
JNIEXPORT void JNICALL Java_com_mwp_ccalljava2_MainActivity_cLog
  (JNIEnv * env, jobject obj){
    //打印log输出
    LOGD("我是C语言打印的debug日志");
    LOGI("我是C语言打印的info日志");
    //通过反射来调用java的方法,需要知道方法签名,使用javap得到方法签名
    //在bin/classes目录下执行 javap -s 全类名
    //1、得到类的字节码对象
    //jclass      (*FindClass)(JNIEnv*, const char*);
    jclass clazz = (*env)->FindClass(env, "com/mwp/ccalljava2/MainActivity");
    //jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID methodID = (*env)->GetMethodID(env, clazz, "show", "(Ljava/lang/String;)V");
    //void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,methodID, (*env)->NewStringUTF(env, "这是弹窗的内容"));
}

参考https://blog.csdn.net/liny000/article/details/83717727

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值