JNI/NDK Development Guide (vii)--c/c++ access to Java instance variables and static variables

Source: Internet
Author: User
Tags function prototype


Reprint Please specify source: http://blog.csdn.net/xyang81/article/details/42836783


In the previous chapter we learned how to access static and instance methods in any Java class in the local code, and in this chapter we will learn about instance variables and static variables in Java, and how to access and modify them in local code. Static variables, also known as class variables (attributes), share the same data in all instance objects and can be accessed directly through the class name. Variable name. Instance variables are also known as member variables (attributes), and each instance has a copy of the instance variable data, and the modified data between them does not affect each other. Let's look at an example:

Package com.study.jnilearn;/** * C + + Access class instance variables and static variables * @author Yangxin */public class Accessfield {private native static Vo ID Accessinstancefield (Classfield obj);p rivate native static void Accessstaticfield ();p ublic static void Main (string[] args) {Classfield obj = new Classfield (); Obj.setnum (ten); Obj.setstr ("Hello");// Local code accesses and modifies Classfield to static properties in Numaccessstaticfield (); Accessinstancefield (obj);//output local code modified value SYSTEM.OUT.PRINTLN ("in Java--->classfield.num = "+ Obj.getnum ()); System.out.println ("in Java--->classfield.str =" + obj.getstr ());} static {system.loadlibrary ("Accessfield");}}

Accessfield is the entry class for the program, defining two native methods: Accessinstancefield and Accessstaticfield, respectively, to demonstrate access to instance variables and static variables in the Java class in native code. Where the Accessinstacefield method accesses an instance variable of a class, the method requires an Classfield instance as a formal parameter to access the instance variables in the object.

Package com.study.jnilearn;/** * Classfield.java * for local code access and modify properties of this class * @author Yangxin * */public class Classfield {private static int num;private String str;public int getnum () {return num;} public void setnum (int num) {classfield.num = num;} Public String Getstr () {return str;} public void Setstr (String str) {this.str = str;}}

In this example, the instance variable and the static variable are not defined in the program entry class, and a new Classfield class is created to define the properties of the class, in order to deepen the ability to access the properties in any Java class in C + + code. An instance variable of type int is defined in this class, NUM, and a static variable of type java.lang.String str. These two variables are accessed and modified by local code.

/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_study_jnilearn_accessfi ELD */#ifndef _included_com_study_jnilearn_accessfield#define _included_com_study_jnilearn_accessfield#ifdef __ Cplusplusextern "C" {#endif */* Class:     Com_study_jnilearn_accessfield * Method:    Accessinstancefield * Signature: (Lcom/study/jnilearn/classfield;) V */jniexport void Jnicall java_com_study_jnilearn_accessfield_ Accessinstancefield  (jnienv *, Jclass, jobject);/* * Class:     Com_study_jnilearn_accessfield * Method:    Accessstaticfield * Signature: () V */jniexport void Jnicall Java_com_study_jnilearn_accessfield_accessstaticfield  (jnienv *, jclass); #ifdef __cplusplus} #endif #endif
The above code is the native code function prototype header file generated by the program entry class Accessfield.class for the native method

Accessfield.c#include "Com_study_jnilearn_accessfield.h"/* * Class:com_study_jnilearn_accessfield * METHOD:ACC Essinstancefield * Signature: () V */jniexport void Jnicall Java_com_study_jnilearn_accessfield_accessinstancefield (    JNIEnv *env, Jclass cls, Jobject obj) {jclass clazz;    Jfieldid FID;    Jstring J_str;    Jstring J_newstr;        const char *C_STR = NULL;    1. Get the class reference clazz = (*env)->getobjectclass (env,obj) of the Accessfield classes;    if (clazz = = NULL) {return; }//2.    Get Accessfield class instance variable str property id FID = (*env)->getfieldid (Env,clazz, "str", "ljava/lang/string;");    if (clazz = = NULL) {return; }//3.        Gets the value of the instance variable str j_str = (jstring) (*env)->getobjectfield (ENV,OBJ,FID); 4.    Converts a Unicode-encoded Java string into a C-style string c_str = (*env)->getstringutfchars (env,j_str,null);    if (c_str = = NULL) {return;    } printf ("in C--->classfield.str =%s\n", c_str);     (*env)->releasestringutfchars (env, J_STR, C_STR);   5.    Modify the value of the instance variable str j_newstr = (*env)->newstringutf (env, "This is C String");    if (j_newstr = = NULL) {return;        } (*ENV)->setobjectfield (env, obj, FID, j_newstr);    6. Delete local references (*env)->deletelocalref (env, clazz);    (*env)->deletelocalref (env, J_STR); (*env)->deletelocalref (env, J_NEWSTR);} /* * Class:com_study_jnilearn_accessfield * Method:accessstaticfield * Signature: () V */jniexport void Jnicall Ja    Va_com_study_jnilearn_accessfield_accessstaticfield (jnienv *env, Jclass cls) {Jclass clazz;    Jfieldid FID;        Jint num;    1. Get class Reference clazz = (*env)->findclass (env, "Com/study/jnilearn/classfield") for Classfield classes;    if (clazz = = NULL) {//error handling return;    }//2. Gets the property ID of the Classfield class static variable num, FID = (*env)->getstaticfieldid (env, clazz, "num", "I");    if (FID = = NULL) {return;    }//3. Gets the value of the static variable num num = (*env)->getstaticintfield (ENV,CLAZZ,FID); printf ("in C--->classfield.num=%d\n ", num);        4. Modify the value of the static variable num (*env)->setstaticintfield (env, Clazz, FID, 80); Delete the genus reference (*env)->deletelocalref (Env,clazz);}
The above code is the implementation of the function prototype in the opponent file.


Run the program and the output is as follows:



Code parsing:


I. Accessing instance variables


In the main method, call the local function Java_com_study_jnilearn_accessfield_accessinstancefield by calling the Accessinstancefield () method, and navigate to the function 32 row:

This function is used to get the value of num in the Classfield object. Here is the prototype of the function:

Jobject (Jnicall *getobjectfield) (jnienv *env, Jobject obj, Jfieldid fieldid);
because the instance variable str is of type string, it belongs to the reference type. In Jni, get the value of the reference type field and call the Getobjectfield function. Similarly, a function that obtains other types of field values is Getintfield,getfloatfield,getdoublefield,getbooleanfield, and so on. These functions have one thing in common, and the function parameters are the same, except that the functions are named differently, and we just need to learn how one of the functions can be called, and so on, and we naturally know how to use other functions.

The Getobjectfield function accepts 3 parameters, env is the JNI function table pointer, obj is the object to which the instance variable belongs, FieldID is the ID of the variable (also known as the property descriptor or signature), and the method descriptor in the previous chapter is the same meaning. The env and obj parameters are available from the java_com_study_jnilearn_accessfield_accessinstancefield function parameter list, so how do you get FieldID? Learn about the children's shoes in Java reflection it should be known that the. Class bytecode file for any class in Java is loaded into memory, and the class sub-code file uses the class class to represent a reference to the class (equivalent to the base class of all classes in Java as Object). Any methods and properties in the class can then be dynamically obtained from the class reference of the classes. Note: Class classes are a separate class in the Java SDK Inheritance system and are not inherited from object. Consider the following example, which dynamically obtains the value of a private instance variable of a class through the Java reflection mechanism:

public static void Main (string[] args) throws Exception {Classfield obj = new Classfield (); Obj.setstr ("yangxin");//Get Clas The class reference of the Sfield bytecode object class<?> clazz = Obj.getclass (); Get the str attribute field field = Clazz.getdeclaredfield ("str");//Remove the permission check because the Java syntax specifies that the non-public attribute is field.setaccessible that cannot be accessed externally ( true);//Gets the value of the str attribute in the obj object String str = (string) field.get (obj); System.out.println ("str =" + str);}
after running the program, the output is of course printing out the value "Yangxin" of the str attribute. So when we call the JNI function in the local code to access a property in the Java object, the first step is to get the class reference to the object, then find the field ID that needs to be accessed in class, and finally call the Getxxxfield series function of the JNI function. Gets the value of the field (property). In the example above, first call the Getobjectclass function to get the class reference of the Classfield:

Clazz = (*env)->getobjectclass (env,obj);

Then call the Getfieldid function to get the ID of the field from the class reference

FID = (*env)->getfieldid (Env,clazz, "str", "ljava/lang/string;");
finally call the Getobjectfield function, pass in the instance object and field ID, get the value of the property
J_str = (jstring) (*env)->getobjectfield (ENV,OBJ,FID);
Call the Setxxxfield series function to modify the value of an instance property, and the last parameter is the value of the property. All reference types call the Setobjectfield function, and the base type calls Setintfield, Setdoublefield, Setbooleanfield, and so on

(*env)->setobjectfield (env, obj, FID, j_newstr);

Second, access to static variables

Accessing static variables and instance variables is different, getting the field ID using Getstaticfieldid, getting and modifying the value of the field using the Get/setstaticxxxfield series functions, such as obtaining and modifying the static variable num in the previous example:

3. Get the value of the static variable num num = (*env)->getstaticintfield (ENV,CLAZZ,FID);//4. Modify the value of the static variable num (*env)->setstaticintfield (env , Clazz, FID, 80);

Summary:

1. Because the JNI function is directly manipulating the data structure in the JVM, it is not limited by the Java access modifier. That is, the JNI function can be called in local code to access non-public properties and methods in the Java object

2. Access and modify instance variable operation step:

1>, call the Getobjectclass function to get the class reference of the instance object

2>, call the Getfieldid function to get the ID of an instance variable in the class reference

3>, call the Getxxxfield function to get the value of the variable, need to pass in the object and variable ID of the instance variable

4>, call the Setxxxfield function to modify the value of the variable, you need to pass in the value of the object, variable ID, and variable that the instance variable belongs to

3. Access and modify static variable operation steps:
1>, call the Findclass function to get the class reference

2>, call the Getstaticfieldid function to get the ID of a static variable in the class reference

3>, call the Getstaticxxxfield function to get the value of a static variable, you need to pass in the reference and variable ID of the class that the variable belongs to

4>, call the Setstaticxxxfield function to set the value of the static variable, you need to pass in the reference of the class to which the variable belongs, the variable ID, and the value

Example code:Https://code.csdn.net/xyang81/jnilearn


JNI/NDK Development Guide (vii)--c/c++ access to Java instance variables and static variables

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.