Learning about JNI in Android (a) some understanding of jnienv

Source: Internet
Author: User

A simple example gives us an initial understanding of the role of JNI, but some of the concepts in JNI need to be understood so that we can better use it to achieve what we want to do.

So how does C + + and Java make calls to each other through JNI?

We know that in Android, when a Java file is compiled into a Dex file, it is loaded by the ClassLoader into the Dalvik VM (DVM), which is interpreted by the DVM and translated into machine language before it can be run by the machine.

For C + +, the source code of the NDK Toolkit provided by Android can be compiled into an executable dynamic library (i.e.. so file), which can then be communicated between Java and C + +.

So, here, it can be imagined that Java's Dex bytecode and the so library of C + + must be running in a DVM at the same time, they use a process space together, otherwise, how can they communicate with each other?

so here, a key middle area is the Dalvik VM. and for C + +, when they are also loaded into the DVM, the function methods implemented by C + + will be loaded into the function table in the DVM.

If you want to adjust the with functions, they must have something that allows them to access the table of functions in the virtual machine.

And this thing is jnienv *.

When we take advantage of the javah generated by the C + + header file, the following:

Jniexport jstring jnicall Java_com_lms_jni_hwdemo_printhello  (jnienv *e, Jobject j) {        return (**e). Newstringutf (E, "Hello from T");}

We can see that this method has two parameters, the first of which is jnienv *, and we have no parameters when we define this method on the Java side, as follows:

Public native String Printhello ();

So what's this jnienv for?in fact, from the name of this parameter can be seen, refers to the environment of JNI, I think it is a reference to the Java Virtual Environment, in Android, refers to the Dalvik VM. Refer to the definition of jnienv in the jni.h file as follows (its definition is somewhat different for C and C + +):
struct _jnienv;struct _javavm;typedef const struct jninativeinterface* c_jnienv; #if defined (__cplusplus) typedef _ JNIEnv jnienv; The type typedef of JNIENV in C + + _JAVAVM JAVAVM; #elsetypedef const struct jninativeinterface* jnienv; C in jnienv type typedef const struct JNIINVOKEINTERFACE* JAVAVM; #endif

In C, we can see that the type of jnienv is jninativeinterface*, which is a pointer type, so what is _jnienv like in C + +?
struct _JNIENV {/    * don't rename this; it does not seem to be entirely opaque/    const struct JNINATIVEINTERFACE* Functions

For C + +, _jnienv is a struct that contains the structure of jninativeinterface*. So as you can see from here, for C and C + +, they refer to jnienv in a slightly different way.In General, jnienv, whether C, or C + +, in fact, the key is the jninativeinterface structure. We can simply look at the definition of the JNINATIVEINTERFACE structure as follows:
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) ;

You can see that there are a lot of function pointers defined in it, and through these definitions, the JNI layer actually obtains a reference to the DVM, which, by defining these function pointers, can locate the JNI function table in the virtual machine and implement the JNI layer function call in the DVM.
So, it can be understood that, in fact, is a jnienv in the DVM Runtime environment, C + + function of a reference, but also because of this, when C + + wants to call the function in the DVM, because it is in the DVM environment, so they must be jnienv* this parameter to obtain these methods Before they can be used.
So when did this jnienv happen?
When the first Java thread in Android wants to invoke the local C/C + + code, the DVM generates a jnienv* pointer to that thread. And each of the lines Cheng C + + is called each other, its corresponding jnienv is also independent of each other.

Well, it's over.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.