A detailed description of the use of JNI in Java Article III: Use of methods in JNIEnv types

Source: Internet
Author: User

Transferred from: http://blog.csdn.net/jiangwei0910410003/article/details/17466369

In the previous article on the use of methods in JNIEnv, let's take a look at how these methods are used by example:

First is the first example: Define a property in Java code, then set it to another value in C + + code, and output it to

First look at the Java code:

[Java]View PlainCopy
  1. Package Com.jni.demo;
  2. Public class Jnidemo {
  3. public int number = 0; Define a property
  4. Define a local method
  5. Public native void SayHello ();
  6. Public static void Main (string[] args) {
  7. Invoke the dynamic-link library
  8. System.loadlibrary ("Jnidemo");
  9. Jnidemo Jnidemo = new Jnidemo ();
  10. Jnidemo.sayhello ();
  11. System.out.print (Jnidemo.number);
  12. }
  13. }

Look at the C + + code:

[CPP]View PlainCopy
  1. #include <iostream.h>
  2. #include "com_jni_demo_jnidemo.h"
  3. Jniexport void Jnicall Java_com_jni_demo_jnidemo_sayhello (jnienv * env, jobject obj)
  4. {
  5. Gets the class object of the object in obj
  6. Jclass clazz = Env->getobjectclass (obj);
  7. Gets the ID of the number field in Java (the last parameter is the signature of number)
  8. Jfieldid Id_number = Env->getfieldid (Clazz,"number","I");
  9. Gets the value of number
  10. Jint number = Env->getintfield (Obj,id_number);
  11. Output to console
  12. cout<<number<<endl;
  13. To change the value of number to 100, it is important to note that jint corresponds to C + + is a long type, so add an L later
  14. Env->setintfield (obj,id_number,100l);
  15. }

After the compilation succeeds, the result after Eclipse is run:


The first 0 is a cout<<number<<endl; in C + + code

The second 100 is the System.out.println (jnidemo.number) in Java;


JNIEnv provides a multitude of call<type>method and Callstatic<type>method, as well as Callnonvirtual<type>method functions, It is necessary to pass the jmethodid of the corresponding method through Getmethodid to the parameters of the above function.

Three forms of the invocation of the sample method:

Call<type>method (jobject obj,jmethodid ID,....);

Call<type>method (jobject obj,jmethodid id,va_list lst);

Call<type>method (jobject obj,jmethodid id,jvalue* v);

The first is the most common way

The second is when the function is called with a va_list variable that points to the parameter table (seldom used)

The third is when you call this function with a pointer to a jvalue or jvalue array.

Description

Jvalue is defined in the JNI.H header file as a union, in C + + we know that the Union can hold different types of values, but when you assign a value to one of these types, the union is this type, for example, if you assign a value to s in Jvalue, The jvalue becomes the Jshort type, so we can define a jvalue array (so that it can contain many types of arguments) to be passed into the method.


If there is one such method in Java now:

boolean function (int a,double B,char c)

{

........

}

(1) Call the function method in C + + using the first way:

Env->callbooleanmethod (obj, id_function, 10L, 3.4, L ' a ')

Obj is an object of method funtion

Id_function is the ID of the method function, which can be obtained through the Getmethodid () method

Then the corresponding parameter, this is similar to the variable parameter in Java, for the last char type parameter l ' A ', why the previous to add an L, because the characters in Java Unicode double-byte, and C + + characters when the single-byte, so to become a wide character, preceded by an L

(2) Use the third Mage in C + + to invoke the function method:

jvalue* args = new jvalue[3];//define Jvalue array

ARGS[0].I = 10l;//i is a jint value in Jvalue

ARGS[1].D = 3.44;

ARGS[2].C = L ' a ';

Env->callbooleanmethod (obj, id_function, args);

Delete[] args;//Whether the pointer heap memory

Example: Calling a method in Java in C + +:

Java code:

Public double max (double value1,double value2) {
Return value1>value2? Value1:value2;
}

This is the time to get the signature of the Max method with JAVAP:


The signature of the Max method is (DD) D

Code in C + +:

[CPP]View PlainCopy
    1. jniexport void jnicall java_ com_jni_demo_jnidemo_sayhello  (jnienv * env, jobject obj)   
    2. {  
    3. //gets the class object of the object in obj   
    4. Jclass clazz = env->getobjectclass (obj);   
    5. //gets the ID of the Max method in Java (the last parameter is the signature of the Max method)   
    6. Jmethodid id_max = env->getmethodid (Clazz,
    7. //call the Max method   
    8. Jdouble doubles = env->calldoublemethod (obj,id_max,1.2,3.4);   
    9. //output return value   
    10. Cout<<doubles <<endl;  
    11. }&NBSP;&NBSP;

After compiling the dynamic file into Eclipse, execute the SayHello method and run the following result:


The maximum value of a successful output


There is a special method in JNIEnv: The Callnonvirtual<type>method method


The first thing to know about the function called is the function method of the subclass, which we all know, but it's not the same in C + +:


This C + + code executes the function method of the parent class, what if you want to execute the function method of the subclass? Then you need to define the function methods of the parent class as virtual virtual functions:


So there's a difference between C + + and Java's methods of inheriting a parent or subclass, and all of the methods in Java are virtual, so the subclass method is always called, so callnonvirtual<type> This method can be used to help us invoke the method of the parent class in Java:

The Callnonvirtual<type>method defined in JNI enables the child class object to invoke the function of the parent class method, and if you want to invoke the parent class method of an object instead of the subclass's method, you can use the callnonvirtual< Type>method, to use it, first to get the parent class and the parent class to call the method of Jmethodid, and then passed to this function can be called through the child class object of the parent method of the overridden

Example: Define the Father class in Java:

[Java]View PlainCopy
    1. Package Com.jni.demo;
    2. Public class Father {
    3. Public void function () {
    4. System.out.println ("father:function");
    5. }
    6. }

In defining a subclass child: Inherit the Father class from the Write function method in the parent class

[Java]View PlainCopy
    1. Package Com.jni.demo;
    2. Public class child extends father{
    3. @Override
    4. Public void function () {
    5. System.out.println ("child:function");
    6. }
    7. }

In Jnidemo code: Defining properties of the Father type

[Java]View PlainCopy
  1. Package Com.jni.demo;
  2. Public class Jnidemo {
  3. Public Father Father = new Child ();
  4. Define a local method
  5. Public native void SayHello ();
  6. Public static void Main (string[] args) {
  7. Invoke the dynamic-link library
  8. System.loadlibrary ("Jnidemo");
  9. Jnidemo Jnidemo = new Jnidemo ();
  10. Jnidemo.sayhello ();
  11. }
  12. }

Take a look at the code in C + +:

[CPP]View PlainCopy
  1. #include <iostream.h>
  2. #include "com_jni_demo_jnidemo.h"
  3. Jniexport void Jnicall Java_com_jni_demo_jnidemo_sayhello (jnienv * env, jobject obj)
  4. {
  5. Gets the class object of the object in obj
  6. Jclass clazz = Env->getobjectclass (obj);
  7. Gets the ID of the Father field in Java (the last parameter is the signature of the Father field)
  8. Jfieldid Id_father = Env->getfieldid (Clazz,"father","lcom/jni/demo/father;");
  9. Gets the object type of the Father field
  10. Jobject father = Env->getobjectfield (Obj,id_father);
  11. Gets the class object of the Father object
  12. Jclass Clazz_father = Env->findclass ("Com/jni/demo/father");
  13. Gets the ID of the function method in the Father object
  14. Jmethodid id_father_function = Env->getmethodid (clazz_father,"function","() V");
  15. Call the function method in the parent class (but the method that executes the subclass)
  16. Env->callvoidmethod (father,id_father_function);
  17. Call the function method in the parent class (execution is the function method in the parent class)
  18. Env->callnonvirtualvoidmethod (father,clazz_father,id_father_function);
  19. }

Compile the successful. dll file and run the results back into eclipse as follows:


Child:function is called Env->callvoidmethod (...) Method of

Father:function is called Env->callnonvirtualmethod (...) Method of

This allows you to control which class's function method is called.

A detailed description of the use of JNI in Java Article III: Use of methods in JNIEnv types

Related Article

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.