Để gọi hàm C++ từ Java, sử dụng JNI (Java Native Interface). Các bước:
- Tạo header file (.h) cho code C++ (dùng
javac -hhoặcjavahcũ). - Viết file C++ (.cpp) implement native method.
- Biên dịch thành Shared Library:
.dll(Windows),.so(Linux/macOS). - Java code: Khai báo method
native, load library bằngSystem.loadLibrary(), gọi method.
Ví dụ hoàn chỉnh
NativeLib.java
public class NativeLib {
static {
System.loadLibrary("native"); // load libnative.so / native.dll
}
// Khai báo native method
public native int add(int a, int b);
public native String greet(String name);
public static void main(String[] args) {
NativeLib lib = new NativeLib();
System.out.println(lib.add(2, 3)); // 5
System.out.println(lib.greet("World")); // Hello, World
}
}
Bước 1: Compile Java & sinh header
javac NativeLib.java
javac -h . NativeLib.java // Sinh NativeLib.h
NativeLib.h (tự động sinh):
/* DO NOT EDIT - generated by javac */
#include <jni.h>
JNIEXPORT jint JNICALL Java_NativeLib_add(JNIEnv*, jobject, jint, jint);
JNIEXPORT jstring JNICALL Java_NativeLib_greet(JNIEnv*, jobject, jstring);
NativeLib.cpp
#include "NativeLib.h"
#include <string>
JNIEXPORT jint JNICALL Java_NativeLib_add(JNIEnv* env, jobject obj, jint a, jint b) {
return a + b;
}
JNIEXPORT jstring JNICALL Java_NativeLib_greet(JNIEnv* env, jobject obj, jstring name) {
const char* cstr = env->GetStringUTFChars(name, nullptr);
std::string result = "Hello, " + std::string(cstr);
env->ReleaseStringUTFChars(name, cstr);
return env->NewStringUTF(result.c_str());
}
Bước 2: Biên dịch shared library
# Linux/macOS
g++ -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux \
-o libnative.so NativeLib.cpp
# Windows (MinGW)
g++ -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" \
-o native.dll NativeLib.cpp
Bước 3: Chạy
# Linux/macOS
java -Djava.library.path=. NativeLib
# Windows
java -Djava.library.path=. NativeLib
Lưu ý quan trọng
- Tên hàm C++ phải khớp chính xác:
Java_<ClassName>_<MethodName>. - JNIEnv* là con trỏ tới JNI interface – dùng để thao tác Java object từ C++.
- Quản lý bộ nhớ cẩn thận:
GetStringUTFChars/ReleaseStringUTFChars,NewStringUTF. - Exception handling: dùng
env->ThrowNew()để ném exception về Java. - Thread safety: JNIEnv chỉ hợp lệ trong thread gắn liền (attached thread).