1. Declaring a Native Method in a Java Class
In Java, use the native keyword to declare a method:
package org.example;
public class Main { public static native void accessNative();
public static void main(String[] args) { // Load the DLL (Windows) or .so (Linux/macOS) using the full path System.load("C:/full/path/to/org_example_Main.dll"); // Change to the actual path accessNative(); }}2. Generating Header Files Using javac -h
Run the following command in the terminal to generate the .h header files:
javac -h . src/org/example/Main.javaπ§ The option
-h .specifies that the.hfiles will be output to the current directory.
3. Creating and Implementing the C Source File
Create a .c source file, for example org_example_Main.c, and copy the corresponding function declarations from the .h header file generated earlier by javac -h.
For example, in org_example_Main.h you might see:
/* * Class: org_example_Main * Method: accessNative * Signature: ()V */JNIEXPORT void JNICALL Java_org_example_Main_accessNative (JNIEnv *, jclass);Please copy this snippet into your .c file and add parameter names (otherwise it wonβt compile):
#include <jni.h>#include "org_example_Main.h"
JNIEXPORT void JNICALL Java_org_example_Main_accessNative (JNIEnv *env, jclass clazz) { // Native logic is implemented here return;}π‘ Tip:
JNIEnv *envis the environment pointer provided by JNI, used to call Java methods, access fields, and more.jclass clazzrepresents the calling class parameter for static methods; for instance methods, it isjobject obj.
4. Compiling to a Shared Library (DLL / SO) Using GCC
Use the appropriate command depending on your operating system:
β
Windows (Generating a .dll)
gcc -I"%JAVA_HOME%\include" ^ -I"%JAVA_HOME%\include\win32" ^ -shared -o org_example_Main.dll org_example_Main.cPS: I have only tested this on
Windows; the instructions forMacandLinuxwere provided by ChatGPT.
β
Linux (Generating a .so)
gcc -I"$JAVA_HOME/include" \ -I"$JAVA_HOME/include/linux" \ -fPIC -shared -o org_example_Main.so org_example_Main.cβ
macOS (Generating a .dylib)
gcc -I"$JAVA_HOME/include" \ -I"$JAVA_HOME/include/darwin" \ -fPIC -dynamiclib -o org_example_Main.dylib org_example_Main.cβ Please make sure that
JAVA_HOMEis properly set and thatgccis installed on your system (on Windows, you can use MinGW).
π§― Error Encountered: Canβt load this .dll (machine code=0x14c)β¦
If you encounter the following error when running Java:
Can't load this .dll (machine code=0x14c) on a AMD 64-bit platformThis means the DLL you compiled is 32-bit (x86), while your JVM is 64-bit (x64), or vice versa.
β
Please use the following command to check which architecture your gcc is:
gcc -dumpmachineYou should see output like this:
x86_64-w64-mingw32 β indicates 64-bitIf you see something like this:
mingw32 β indicates 32-bit βIt means you are using the wrong architecture compiler and should switch to the 64-bit version.
β Solution
You can use MSYS2 to install the 64-bit MinGW:
pacman -S mingw-w64-ucrt-x86_64-gccThen open the MSYS2 MinGW 64-bit terminal (or add the ucrt-x86_64-gcc directory to your environment variables), and recompile your C file into a 64-bit .dll using the gcc in that environment:
gcc -I"$JAVA_HOME/include" \ -I"$JAVA_HOME/include/win32" \ -shared -o org_example_Main.dll org_example_Main.cβ Make sure the DLL architecture matches the JVM architecture to load and run smoothly!