JNIEnv的使用在C和C++中的区别

JNIEnv的使用在C和C++中的区别,第1张

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动态注册简单示例(上)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10157145.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存