The Java Native Interface (aka JNI) allows Java code to interoperate with C/C++ code.
These are notes taken from https://docs.oracle.com/en/java/javase/18/docs/specs/jni/
How does Java code interoperate with C/C++ code (aka "native code") ?
There are two parts to this question:
- How does Java code call native code?
- How does native code call Java code?
Let's tackle each question separately.
- You code up C/C++ methods that can be called from Java code. These methods will be the entrypoints to the C/C++ world coming from the Java world. Such entrypoint methods are known as native methods.
- Native methods receive parameters coming from Java (we'll look at the mapping between Java types and C/C++ types later). Its return value is returned back to the Java world.
- You create a C/C++ library implementing and exposing the desired native methods. Then you load this library into the JRE. This library is referred to as a native library.
- From Java, you load the native library with the
System.loadLibrary()
method. You also need to declare the native method in Java with thenative
keyword. Declare = only provide the method's header.
For example,
package com.example.application;
class MyClass {
native double f(int i, String s);
static {
System.loadLibrary("my_lib");
}
}
In this example, a library called my_lib
is being loaded into the JRE. This library should
contain the definition of the native method f()
. The native method f()
is declared in Java
as well so it's callable/reachable from Java code.
- This question can be generalized to "how does C/C++ code access Java VM features?".
Calling your Java code from C/C++ is an example of accessing Java VM features.
- C/C++ code accesses Java VM features by calling JNI functions (aka "interface
functions").
- To call a JNI function, you need the current thread's **JNI interface pointer**
(aka "interface pointer"). You call a JNI function through that pointer.
- A JNI interface pointer is associated to a given thread and can only be used from
that thread. A native method, therefore, must not pass the JNI interface pointer from one thread
to another.
- The C/C++ entrypoint methods that are called from Java are known as "native methods". These methods are the entrypoint to the C/C++ world coming from the Java world.
- Native methods receive the calling thread's JNI interface pointer as their first argument.
- Native methods are loaded with the
System.loadLibrary()
method.