
Java调用C和C++函数时的JNI使用区别:
注意:jnih头文件中对于c & cpp采用不同的定义
在C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针
C形式需要对env指针进行双重deferencing,而且须将env作为第一个参数传给jni函数
jclass (JNICALL GetObjectClass) (JNIEnv env, jobject obj);
jclass GetObjectClass(jobject obj)
{
return functions->GetObjectClass(this,obj);
}
对于c
1jclass test_class = (env)->GetObjectClass(env, obj);
2jfieldID id_num = (env)->GetFieldID(env, test_class, "num", "I");
对于 cpp
1jclass test_class = env->GetObjectClass(obj);
2jfieldID id_num = env->GetFieldID(test_class, "num", "I");
在 C 中,
JNI 函数调用由“(env)->”作前缀,目的是为了取出函数指针所引用的值。
在 C++ 中,
JNIEnv 类拥有处理函数指针查找的内联成员函数。
下面将说明这个细微的差异,其中,这两行代码访问同一函数,但每种语言都有各自的语法。
C 语法:jsize len = (env)->GetArrayLength(env,array);
C++ 语法:jsize len =env->GetArrayLength(array);
java数组传递给jni实际是指针,只是java禁止你直接在jni里对java数组 *** 作,所以在jni需要对java数组转换为jni里可以 *** 作的数组。典型的还有字符串,c struct等。
之所以禁止jni直接 *** 作数组可能是jvm在安全等方面的考虑。jni调用涉及到java内存栈和native内存栈。jvm只能处理到java内存,没有实现自动管理jni调用的内存。试想下如果jni里 *** 作java数组刚好被回收了会怎样?
所以在jni里需要拷贝java数组副本,而且分配或者是引用了对象,需要手动释放删除(DeleteLocalRef、ReleaseXX)。jni调用实际是个很大的开销
jni动态注册是性能最优的方案。写这个的原因是jni使用的过程中坑比较多,方便此前没有接触过的朋友快速构架开发编译环境。
如果使用jna,只需要通用的c type函数导出的dll就可以了。如果是android使用的话Android studio自带cmake,这里不多讲。
win10 vs2019 cmake-319 idea jdk-8( >
以上就是关于JNIEnv的使用在C和C++中的区别全部的内容,包括:JNIEnv的使用在C和C++中的区别、Java通过JNI调用C 传递参数时,想传递地址,怎么实现、c++的jni动态注册简单示例(上)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)