一个简单的样例让我们初步地了解JNI的作用。可是关于JNI中的一些概念还是需要了解清楚,才干够更好的去利用它来实现我们想要做的事情。

那么C++和Java之间的是怎样通过JNI来进行互相调用的呢?

我们知道,在Android中,当Java文件被编译成dex文件之后。会由类载入器载入到Dalvik VM(DVM)中,由DVM来进行解释,翻译成机器语言之后。才干由机器来执行。

而对于C/C++来说,其源码经由Android提供的NDK工具包,能够编译成可执行动态库(即.so文件),之后,Java和C++之间就能够进行通讯了。

那么,在这里,能够想像,Java的Dex字节码和C/C++的so库肯定是同一时候执行在一个DVM之中,它们是共同使用一个进程空间的,否则,它们怎么彼此沟通呢?

所以在这里,一个关键的中间区域就是Dalvik VM。而对于C/C++,当它们也被载入进DVM之后。由C/C++实现的函数方法等都会被载入在DVM中的函数表中。

假设想要在C/C++中调用函数。它们必需要有个东西能够让其訪问到这个虚拟机中的函数表。

而这个东西就是JNIEnv *。

当我们利用javah生成的C/C++的头文件的时候,例如以下:

JNIEXPORT jstring JNICALL Java_com_lms_jni_HwDemo_printHello
(JNIEnv *e, jobject j)
{
return (**e).NewStringUTF(e,"Hello from T" );
}

我们能够看到这种方法有两个參数,当中第一个就是JNIEnv *,而我们在Java端定义这种方法的时候。是没有參数的。例如以下:

public native String printHello();
那么这个JNIEnv是干什么用的?
事实上从这个參数的名称就能够看到,就是指JNI的执行环境,我认为它就是对Java虚拟环境的一个引用。在Android中,就是指Dalvik VM。
參考jni.h文件里关于JNIEnv的定义,例如以下(对于C和C++,它的定义有点不一样):
struct _JNIEnv;
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIEnv; #if defined(__cplusplus)
typedef _JNIEnv JNIEnv; //C++中JNIEnv的类型
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv; //C中JNIEnv的类型
typedef const struct JNIInvokeInterface* JavaVM;
#endif

在C中,我们能够看到JNIEnv的类型就是JNINativeInterface* ,是一个指针类型,那么在C++中呢,_JNIEnv是什么样的呢?

struct _JNIEnv {
/* do not rename this; it does not seem to be entirely opaque */
const struct JNINativeInterface* functions;

而对于C++来说, _JNIEnv是一个结构体,里面包括了JNINativeInterface*的结构。

所以从这里也能够看到。对于C和C++来说,它们引用JNIEnv中的方法是有一点不一样的。

总的来说。JNIEnv,无论是C。还是C++。事实上关键都是JNINativeInterface的这个结构。

我们能够简单看一下JNINativeInterface结构的定义,例如以下:
struct JNINativeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3; jint (*GetVersion)(JNIEnv *); jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
jsize);
jclass (*FindClass)(JNIEnv*, const char*); jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);
jfieldID (*FromReflectedField)(JNIEnv*, jobject);
/* spec doesn't show jboolean parameter */
jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);

能够看到在它当中定义了非常多的函数指针,而通过这些定义,JNI层事实上就获得了对DVM的引用,通过定义的这些函数指针,能够定位到虚拟机中的 JNI 函数表。从而实现JNI层在DVM中的函数调用。

所以,能够这样理解,事实上JNIEnv。就是对DVM执行环境中C/C++函数的一个引用。而也正由于此,当C/C++想要在DVM中调用函数的时候。由于其是在DVM的环境中。所以它们必须通过JNIEnv* 这个參数来获得这些方法,之后才干够使用。
那么这个JNIEnv是什么时候产生的呢?
当Android中第一个Java线程要调用本地的C/C++代码的时候。DVM就会为该线程产生一个JNIEnv*的指针。而每个线程在和C/C++互相调用的时候。其相应的JNIEnv 也是相互独立。

嗯,结束。

Android中关于JNI 的学习(一)对于JNIEnv的一些认识的更多相关文章

  1. Android中关于JNI 的学习(零)简单的样例,简单地入门

    Android中JNI的作用,就是让Java可以去调用由C/C++实现的代码,为了实现这个功能.须要用到Anrdoid提供的NDK工具包,在这里不讲怎样配置了,好麻烦,配置了好久. . . 本质上,J ...

  2. Android中关于JNI 的学习(三)在JNI层訪问Java端对象

    前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...

  3. Android中关于JNI 的学习(四)简单的样例,温故而知新

    在第零篇文章简单地介绍了JNI编程的模式之后.后面两三篇文章,我们又针对JNI中的一些概念做了一些简单的介绍,也不知道我究竟说的清楚没有.但相信非常多童鞋跟我一样.在刚開始学习一个东西的时候,入门最好 ...

  4. Android中关于JNI 的学习(六)JNI中注冊方法的实现

    在前面的样例中,我们会发现,当在Java类中定义一个方法的时候,例如以下: public class ParamTransferTest { public static int testval = 1 ...

  5. Android中关于JNI 的学习(五)在C文件里使用LogCat

    Log是开发过程中.对于我们调试程序非常重要的一个工具,有非常多时候,我们正是通过Log才干够看清楚程序是不是真的依照我们想像中的模式在跑,从而定位到问题所在的地方.而在Android开发中,毫无疑问 ...

  6. Android中的SQLite使用学习

    Android中的SQLite使用学习 SQLite是非常流行的嵌入式关系型数据库,轻载, 速度快,而且是开源.在Android中,runtime提供SQLite,所以我们可以使用SQLite,而且是 ...

  7. android中使用jni对字符串加解密实现分析

    android中使用jni对字符串加解密实现分析 近期项目有个需求.就是要对用户的敏感信息进行加密处理,比方用户的账户password,手机号等私密信息.在java中,就对字符串的加解密我们能够使用A ...

  8. 深入理解Android(5)——从MediaScanner分析Android中的JNI

    前面几篇介绍了Android中的JNI和基本用法,这一篇我们通过分析Android源代码中的JNI实例,来对JNI部分做一个总结. 一.通向两个不同世界的桥梁 在前面我们说过,JNI就像一个桥梁,将J ...

  9. 深入理解Android(2)——理解Android中的JNI(中)

    阳光小强参加了CSDN博客之星评选,如果你觉得阳光小强的博客对你有所帮助,为小强投上一票吧:http://vote.blog.csdn.net/blogstar2014/details?usernam ...

随机推荐

  1. windows监听socket和标准输入

    原来的代码 def input_command(self): msg = raw_input('\nPlease input the command:') remote_id = raw_input( ...

  2. HTML5实现手机QQ表情功能

    主要素材和JS来自QQ空间触屏版( http://m.qzone.com ),我只是代码的搬运工.代码下载. 预览请使用较新版的Chrome,然后启用开发者工具,设备模式.详见:(http://www ...

  3. JFreeChart DateAxis用法

    http://blog.csdn.net/xiaozhendong123/article/details/50131513

  4. 微信小程序:全局配置app.json

    微信小程序:全局配置app.json 一.全局配置app.json app.json文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. 以下是一个包 ...

  5. 20145211《网络对抗》注入Shellcode并执行&&Return-to-libc攻击

    Shellcode注入 基础知识 Shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并将堆栈的返回地址利用缓冲区溢出,覆盖成为指向 shellcode的地址. ...

  6. OpenVAS安装过程

    OpenVAS安装过程 安装过程 检查安装状况 命令行下输入opensav-check-setup,显示错误NO CA certificate file,并显示解决方法 创建证书 输入命令openva ...

  7. IC行业

    定位IC行业,其实很简单. 我不是IC数据统计的专家,但是可以看出IC行业的发展: 在20年前,毛利是1000%,行业增长在每年20%以上 在10年前,毛利是200%,行业增长在每年10%以上 在现在 ...

  8. Execution Order for the ApiController

    Execution Order for the ApiController Assuming the request goes into the ApiController scope, the op ...

  9. office的project的激活码

    8XWTK-7DBPM-B32R2-V86MX-BTP8PMVR3D-9XVBT-TBWY8-W3793-FR7C326K3G-RGBT2-7W74V-4JQ42-KHXQWD4HF2-HMRGR-R ...

  10. 【p4tutorials】P4 v1.1 Simple Router

    fork了p4tutorials,想从里面窥探一些门道. 本文相关的原文链接:ReadMe 说明: 下面的这个P4程序,是当下最著名的 simple_router 程序的一个版本,是根据P4的1.1版 ...