Learn Java

Access Properties And Methods From Native Code

Implementation

This example can be found in AccessProperties.

AccessProperties.java

    ...
    public static void main(String args[]) {
        InstanceAccess instanceAccessor = new InstanceAccess();
        //Set the initial value of the name property
        instanceAccessor.setName("Jack");
        System.out.println("Java: value of name = \""+ instanceAccessor.name +"\"");
        //Call the propetyAccess() method
        System.out.println("Java: calling propertyAccess() method...");
        instanceAccessor.propertyAccess(); //5
        //Value of name after calling the propertyAccess() method
        System.out.println("Java: value of name after calling propertyAccess() = \""+ instanceAccessor.name +"\"");
        //Call the methodAccess() method
        System.out.println("Java: calling methodAccess() method...");
        instanceAccessor.methodAccess(); //6
        System.out.println("Java: value of name after calling methodAccess() = \""+ instanceAccessor.name +"\"");
    }
    ...

AccessProperties.c

JNIEXPORT void JNICALL Java_InstanceAccess_propertyAccess(JNIEnv *env, jobject object)
{
    jfieldID fieldId;
    jstring jstr;
    const char *cString;

    /* Getting a reference to object class */
    jclass class = (*env)->GetObjectClass(env, object); /* 1 */

    /* Getting the field id in the class */
    fieldId = (*env)->GetFieldID(env, class, "name", "Ljava/lang/String;"); /* 2 */
    if (fieldId == NULL) {
        return; /* Error while getting field id */
    }

    /* Getting a jstring */
    jstr = (*env)->GetObjectField(env, object, fieldId); /* 3 */

    /* From that jstring we are getting a C string: char* */
    cString = (*env)->GetStringUTFChars(env, jstr, NULL); /* 4 */
    if (cString == NULL) {
        return; /* Out of memory */
    }
    printf("C: value of name before property modification = \"%s\"\n", cString);
    (*env)->ReleaseStringUTFChars(env, jstr, cString);

    /* Creating a new string containing the new name */
    jstr = (*env)->NewStringUTF(env, "Brian"); /* 5 */
    if (jstr == NULL) {
        return; /* Out of memory */
    }
    /* Overwrite the value of the name property */
    (*env)->SetObjectField(env, object, fieldId, jstr); /* 6 */
}

JNIEXPORT void JNICALL Java_InstanceAccess_methodAccess (JNIEnv *env, jobject object)
{

    jclass class = (*env)->GetObjectClass(env, object); /* 7 */
    jmethodID methodId = (*env)->GetMethodID(env, class, "setName", "(Ljava/lang/String;)V"); /* 8 */
    jstring jstr;
    if (methodId == NULL) {
        return; /* method not found */
    }
    /* Creating a new string containing the new name */
    jstr = (*env)->NewStringUTF(env, "Nick"); /* 9 */
    (*env)->CallVoidMethod(env, object, methodId, jstr); /* 10 */
}

Explains

JNI Methods:

  • GetObjectClass: getting a reference to the object class
  • GetFieldID: Gets a field Id from the object class, specifying the property to get and the internal type.
  • SetObjectField

    More information can be found on the SE Documentation.

  • GetObjectField: get the value of the property in the native type.
  • SetObjectField
  • NewStringUTF: create a new java String.
  • GetMethodID
  • CallVoidMethod

Signature

Java VM Type Signatures:

Signature Java Type
V void
Z boolean
B byte
C char
S short
I int
J long
F float
D double
Lfully-qualified-class; fully-qualified-class
[type type[]
(arg-types)ret-type method type

Here is an tutoiral.

Result

Java: value of name = "Jack"
Java: calling propertyAccess() method...
C: value of name before property modification = "Jack"
Java: value of name after calling propertyAccess() = "Brian"
Java: calling methodAccess() method...
Java: value of name after calling methodAccess() = "Nick"