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.h
files 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 *env
is the environment pointer provided by JNI, used to call Java methods, access fields, and more.jclass clazz
represents 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.c
PS: I have only tested this on
Windows
; the instructions forMac
andLinux
were 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_HOME
is properly set and thatgcc
is 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 platform
This 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 -dumpmachine
You should see output like this:
x86_64-w64-mingw32 β indicates 64-bit
If 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-gcc
Then 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!