Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Cách gọi hàm C++ từ Java (JNI)

Để gọi hàm C++ từ Java, sử dụng JNI (Java Native Interface). Các bước:

  1. Tạo header file (.h) cho code C++ (dùng javac -h hoặc javah cũ).
  2. Viết file C++ (.cpp) implement native method.
  3. Biên dịch thành Shared Library: .dll (Windows), .so (Linux/macOS).
  4. Java code: Khai báo method native, load library bằng System.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).