You are on page 1of 33

Java Native Interface (Java

Method)
Lecture 9

Java Method: https://www.youtube.com/watch?v=Lk9gENfROOc and https://www.youtube.com/watch?v=QvDN-OLv-


Instance and Static Method (Revision)
Java Method

Instance Method Static Method

• It is a method defined for an object • It is a method defined for a class


• It must be invoked on a specific object • It is invoked independent of any
of class object
• It can access static & instance • It can only access static variables
variables and methods and methods
Syntax: ObjectName.MethodName( ) Syntax: ClassName.MethodName( )

Ex: Student ab = new Student(); Ex: Student.Method2();


ab.Method1(); static method
instance method

object is same as instance


Instance Method
Calling Instance Method
To call the instance method in JNI:
1. Find class reference of the object
GetObjectClass( )

2. Find method id of the instance method


GetMethodID( )

3. Call the correct instance method


Call<Type>Method( )

Type refers to data type used in Java


Calling Instance Method (Example 1)
Java source code: BookM.java C++ native code: CBookM.cpp
field/method declaration: input parameters:
instance method: void show( ) interface pointer: env
native method: void read( ) object reference: obj

Static block: 1. GetObjectClass( )


load CBookM.dll => BookM class of object c
2. GetMethodID( )
main function: => methodID of show( )
BookM object: c 3. CallVoidMethod( )
c.read( ) => Call the show( )

GetVoidMethod because return type of show() is void data type.


Calling Instance Method (Example 1)
Java source code:
BookM.java
class BookM{
private native void read();

private void show(){


System.out.println("The is book information.");
}

static {
System.loadLibrary("CBookM");
}

public static void main (String args[]){


BookM c = new BookM();
C++ native code: CBookM.cpp
c.read(); #include "BookM.h"
}
} JNIEXPORT void JNICALL Java_BookM_read(JNIEnv *env, jobject obj) {
jclass cls = env->GetObjectClass(obj);
jmethodID mid = env->GetMethodID(cls, "show", "()V");

if (mid == NULL) return;

env -> CallVoidMethod(obj, mid); // call the show()


}
Calling Instance Method (Example 1)
Compilation Process of JNI
// Step 2: compile Java source code

// Step 4: build shared library file (CBookM.dll)

// Step 5: execute Java program

Step 1: write Java source code (BookM.java)


Step 3: write C++ native code (CBookM.cpp)
Calling Instance Method
Assume: JNIEXPORT jint JNICALL Java_BookM_read(JNIEnv *env, jobject obj)

Step 1: Find the class reference using GetObjectClass() function


JNI interface pointer object reference

It returns the class reference


jclass cls = env->GetObjectClass(obj);
(class of an object).
class reference

Step 2: Get the method ID using GetMethodID() function


method descriptor
It returns the method
jmethodID mid = env->GetMethodID(cls, "show", "()V"); ID. It return NULL if
operation fails.
method id
show() is an instance method (no input argument and return nothing) in Java class
Calling Instance Method
Assume: JNIEXPORT jint JNICALL Java_BookM_read(JNIEnv *env, jobject obj)
<Type> refers to data type used in Java

Step 3: Call the instance method using Call<Type>Method() function


object reference method id

env->Call<Type>Method(obj, mid);
It calls the specific
instance method from Java
env->CallVoidMethod(obj, mid); class

• If the instance method return float value, CallFloatMethod() is used.


instance method return nothing • If the instance method return String value, CallObjectMethod() is used.
• If the instance method return nothing and having the input argument,
e.g. void show(int a, double b),

env->CallVoidMethod(obj, mid, 10, 6.8);

value for a value for b


Call<Type>Method Function
Return Type Call<Type>Method
void CallVoidMethod()
jboolean CallBooleanMethod()
jbyte CallByteMethod()
jchar CallCharMethod()
Primitive type jshort CallShortMethod()
jint CallIntMethod()
jlong CallLongMethod()
jfloat CallFloatMethod()
jdouble CallDoubleMethod()
jobject CallObjectMethod()
Class type jstring CallObjectMethod()
Method Signature/Descriptor
 Before calling a Java object's method from JNI, the
method signature of that particular method need to be
assigned in JNI.
 Example, long myMethod (int n, String s, int[] arr);
 Method signature is (ILjava/lang/String;[I)J
method’s arguments return type
 There are two parts to the signature.
 The first part is enclosed within the parentheses and represents
the method's arguments.
 The second portion follows the closing parenthesis and
represents the return type.
Method Signature/Descriptor cont..
Java Type Field Signature/Descriptor
boolean Z
byte B
char C
short S
int I
long J
float F
double D
void V
String Ljava/lang/String;
array [
Example of Method Signature/Descriptor
List the method signature of the function below:
1. private void callback();
()V
2. private char ReadT (boolean b);
(Z)C
3. public void SampleMethod(int n, boolean b);
(IZ)V
4. double[] Test (String s, boolean T);
(Ljava/lang/String;Z)[D
Calling Instance Method (Example 2)
Java source code: BookP.java C++ native code: CBookP.cpp
field/method declaration: input parameters:
instance field: boolean status interface pointer: env
instance method: object reference: obj
1. void setStatus(boolean y)
2. void showStatus( ) 1. GetObjectClass( )
native method: void read( ) => BookP class of object c
2. GetMethodID( )
Static block: Þ methodID of setStatus( )
load CBookP.dll Þ methodID of showStatus( )
3. CallVoidMethod( )
main function: Þ Call the setStatus( )
BookP object: c Þ Call the showStatus( )
c.read( )

GetVoidMethod because return type of setStatus() and showStatus() are void data type.
Calling Instance Method (Example 2)
Java source code: BookP.java
class BookP{
private boolean status;
private native void read();

private void setStatus (boolean y){


status = y;
}
private void showStatus(){
System.out.println ("The book status is " + status); C++ native code: CBookP.cpp
}
static { #include "BookP.h"
System.loadLibrary("CBookP");
} JNIEXPORT void JNICALL Java_BookP_read(JNIEnv *env, jobject obj) {
public static void main (String args[]){
BookP c = new BookP(); jclass cls = env->GetObjectClass(obj);
c.read(); jmethodID mid1 = env->GetMethodID(cls, "setStatus", "(Z)V");
} jmethodID mid2 = env->GetMethodID(cls, "showStatus", "()V");
}
if (mid1 && mid2 == NULL) return;

env -> CallVoidMethod(obj, mid1, 1); // call setStatus()


env -> CallVoidMethod(obj, mid2); // call showStatus()
}

value of 1 represents true value that will be passed to the setStatus( )


Calling Instance Method (Example 2)
Compilation Process of JNI
// Step 2: compile Java source code

// Step 4: build shared library file (CBookP.dll)


// Step 5: execute Java program

Step 1: write Java source code (BookP.java)


Step 3: write C++ native code (CBookP.cpp)
Static Method
Calling Static Method
To call the static method in JNI:
1. Find class reference of the object
GetObjectClass( )

2. Find method id of the static method


GetStaticMethodID( )

3. Call the correct static method


CallStatic<Type>Method( )

Type refers to data type used in Java


Calling Static Method (Example 1)
Java source code: BookH.java C++ native code: CBookH.cpp
field/method declaration: input parameters:
static method: void check(double x) interface pointer: env
native method: void read( ) object reference: obj

Static block: 1. GetObjectClass( )


load CBookH.dll => BookH class of object c
2. GetStaticMethodID( )
main function: Þ methodID of check( )
BookH object: c 3. CallStaticVoidMethod( )
c.read( ) Þ Call the check( )

GetStaticVoidMethod because return type of check() is void data type.


Calling Static Method (Example 1)
#include "BookH.h" C++ native code: CBookH.cpp
JNIEXPORT void JNICALL Java_BookH_read(JNIEnv *env, jobject obj) {

jclass cls = env->GetObjectClass(obj);


jmethodID mid = env->GetStaticMethodID(cls, "check", "(D)V");

if (mid == NULL) return;


Java source code: BookH.java
class BookH{ env -> CallStaticVoidMethod(cls, mid, 25.99);
private native void read(); }

private static void check(double x){ Call the check method by passing value of 25.99 as input parameter
System.out.println("Price of the book = RM" + x);
}

static {
System.loadLibrary("CBookH");
}
public static void main (String args[]){
BookH c = new BookH();
c.read();
}
}
Calling Static Method (Example 1)
Compilation Process of JNI

// Step 2: compile Java source code

// Step 4: build shared library file (CBookP.dll)

// Step 5: execute Java program

Step 1: write Java source code (BookH.java)


Step 3: write C++ native code (CBookH.cpp)
Calling Static Method
Assume: JNIEXPORT jint JNICALL Java_BookH_read(JNIEnv *env, jobject obj)

Step 1: Find the class reference using GetObjectClass() function


JNI interface pointer object reference

It returns the class reference (class


jclass cls = env->GetObjectClass(obj); of an object).

class reference

Step 2: Get the method ID using GetStaticMethodID() function


method descriptor It returns the
method ID of
jmethodID mid = env->GetStaticMethodID(cls, "check", "(D)V"); static method.
It return NULL
if operation fails.
method id
check() is a static method (double type of input argument and return nothing) in Java class
Calling Static Method
Assume: JNIEXPORT jint JNICALL Java_BookH_read(JNIEnv *env, jobject obj)

<Type> refers to data type used in Java

Step 3: Call the static method using CallStatic<Type>Method() function


class reference method id

env->CallStatic<Type>Method(cls, mid);
It calls the specific static
method from Java class.
env->CallStaticVoidMethod(cls, mid);

• If the static method return float value, CallStaticFloatMethod() is used.


static method return nothing • If the static method return String value, CallStaticObjectMethod() is used.
• If the static method return nothing and having the input argument, e.g.
void check(int a),

env->CallStaticVoidMethod(cls, mid, 10);

value for a
CallStatic<Type>Method Function
Return Type CallStatic<Type>Method
void CallStaticVoidMethod()
jboolean CallStaticBooleanMethod()
jbyte CallStaticByteMethod()
jchar CallStaticCharMethod()
Primitive type jshort CallStaticShortMethod()
jint CallStaticIntMethod()
jlong CallStaticLongMethod()
jfloat CallStaticFloatMethod()
jdouble CallStaticDoubleMethod()
jobject CallStaticObjectMethod()
Class type jstring CallStaticObjectMethod()
Calling Static Method (Example 2)
Java source code: BookS.java C++ native code: CBookS.cpp
field/method declaration: input parameters:
static method: int multiple(int x) interface pointer: env
native method: void read( ) object reference: obj

Static block: 1. GetObjectClass( )


load CBookS.dll => BookS class of object c
2. GetStaticMethodID( )
main function: Þ methodID of multiple( )
BookS object: c 3. CallStaticIntMethod( )
c.read( ) Þ Call the multiple( )

GetStaticIntMethod because return type of multiple() is int data type.


Calling Static Method (Example 2)
#include <iostream> C++ native code: CBookS.cpp
#include "BookS.h"

using namespace std;

JNIEXPORT void JNICALL Java_BookS_read(JNIEnv *env, jobject obj) {

jclass cls = env->GetObjectClass(obj);


Java source code: BookS.java jmethodID mid = env->GetStaticMethodID(cls, "multiple", "(I)I");
class BookS{
private native void read(); if (mid == NULL) return;

private static int multiple (int x){ jint result = env -> CallStaticIntMethod(cls, mid, 8); //call multiple()
return x*x; cout<<"This result is "<< result;
} }
passing the value of 8 as input parameter
static {
System.loadLibrary("CBookS");
}
public static void main (String args[]){
BookS c = new BookS();
c.read();
}
}
Calling Static Method (Example 2)
Compilation Process of JNI
// Step 2: compile Java source code

// Step 4: build shared library file (CBookP.dll)

// Step 5: execute Java program

Step 1: write Java source code (BookS.java)


Step 3: write C++ native code (CBookS.cpp)
Extra Exercise (Q1)
import java.util.Scanner;

class Q5{
public native void printLength(String name);

static {
System.loadLibrary("CQ5");
}

public static void main(String[] args) {


Scanner ab = new Scanner(System.in);
System.out.printf("Please enter your name: ");
String name = ab.nextLine();

Q5 ww = new Q5();
ww.printLength(name);
}
}
Extra Exercise (Q1)
#include "Q5.h"
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_Q5_printLength(JNIEnv *env, jobject obj, jstring


text) {

const char *str = env->GetStringUTFChars(text, NULL);


cout<< "Hi " << str << "\n";

jint length = env->GetStringLength(text);


cout << "Length of your name (include whitespace): " << length;

env->ReleaseStringUTFChars(text, str);

return;
}
Extra Exercise (Q1)
Extra Exercise (Q2)
import java.util.Scanner;

class Q6 {
public native String printNum(int num);

static {
System.loadLibrary("CQ6");
}

public static void main(String[] args) {


Scanner ab = new Scanner(System.in);
System.out.printf("Please enter your magic number: ");
int num = ab.nextInt();

Q6 ww = new Q6();
System.out.print("The result is " + ww.printNum(num));
}
}
Extra Exercise (Q2)
#include "Q6.h"
#include <cstring>

JNIEXPORT jstring JNICALL Java_Q6_printNum(JNIEnv *env, jobject obj, jint nn) {

char temp[20];
jstring result;

if (nn%2 == 0)
strcpy(temp, "even number");
else
strcpy(temp, "odd number");

result = env->NewStringUTF(temp);
return result;
}
Extra Exercise (Q2)

You might also like