cmake + JNI

laremehpe發表於2024-07-15

目錄結構:

|-HelloWorld
|--src
|---main
|----java
|-----main.java
|----cpp //和java目錄同級
|----CMakeLists.txt //cmake配置檔案
|-----src // c\c++ 原始檔目錄
|------HelloWorld.cpp
|-----build // 生成檔案目錄
|-----include //標頭檔案目錄
|-----lib //依賴檔案目錄

建立java程式:

public class HelloWorld {
//靜態載入庫檔案
// 需要注意load方法需要提供完整的路徑, loadLibrary 只需要提供名稱就可以了,可以自動載入.class資料夾下的對應名稱的dll檔案
//    static {
//        System.loadLibrary("native"); 
//        System.load(System.getProperty("user.dir") + "\\..\\cpp\\build\\native.dll"); 
//    }

    //庫檔案提供的方法
    public native void printHelloWorld();

    public static void main(String[] args) {
        //動態載入庫檔案
        System.load("C:\\Users\\djatm\\Desktop\\temp\\JNIHelloWorld-main\\src\\main\\cpp\\build\\libnative.dll");
       
        HelloWorld helloWorld = new HelloWorld();
         //呼叫提供的方法
        helloWorld.printHelloWorld();
    }
}

然後用cmd切換到HelloWorld.java 的目錄下執行命令:

javac -h . HelloWorld.java

生成檔案:

cmake + JNI

將生成的HelloWorld.h 放入到 cpp下面的 include目錄 並 實現相應方法

#include <jni.h> // 引入Java預定義宏
#include <iostream>
#include "HelloWorld.h" //生成的標頭檔案

void sayHello(){
  std::cout << "Hello from C++ !!" << std::endl;
}
JNIEXPORT void JNICALL Java_HelloWorld_printHelloWorld
  (JNIEnv* env, jobject thisObject) {
    sayHello();
}

並配置CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
 set(CMAKE_CXX_STANDARD 11)
 project(test)

 set(SRC src/HelloWorld.cpp) # 配置cpp原始檔到SRC變數中

 set(EXECUTABLE_OUTPUT_PATH ./build) #配置輸出目錄

 set(JAVA_HOME $ENV{JAVA_HOME}) #獲取系統環境變數中的JAVA_HOME並設定到JAVA_HOME 變數中

 include_directories( #引入的標頭檔案位置
	include
	${JAVA_HOME}/include
	${JAVA_HOME}/include/win32
	 )

 add_library(native SHARED ${SRC}) #生成動態庫

cmd切換到cpp的build目錄執行命令:

cmake .. -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -G "MinGW Makefiles" -DCMAKE_MAKE_PROGRAM=C:/mingw64/bin/make.exe

然後執行命令

make

得到dll檔案:

cmake + JNI

最後執行

cmake + JNI

相關文章