android jni C/C++ 层和java层 进程间共享数据
android jni C/C++ 层和java层 进程间共享数据,原理利用 linux 文件的特性,访问同一文件名的句柄,然后再此基础上,mmap数据空间。非常简单,粗暴的处理方式,此方法不需要向进程间传递fd句柄。当然如果一定要传,方法是: 将句柄往java层送,利用java封装的函数打包句柄,然后用blind 传送,进程B也利用java层接口 解出句柄,不是简单传进程A的fd,那是无效的。进
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, "这是弹窗的内容")); }
更多推荐
所有评论(0)