jni 极简示例

1

prepare wsl

apt update
apt install gcc
apt install cmake
apt install make
apt install gdb

public class HelloWorld {
    static {
        System.loadLibrary("hello");
    }

    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        String hello = helloWorld.displayHelloWorld("hello");
        System.out.println(hello);

        byte[] bytes = helloWorld.readFile("/mnt/c/Users/zhangbaowei/Desktop/test.txt");

        System.out.println(new String(bytes));

    }

    public native String displayHelloWorld(String input);

    public native byte[] readFile(String input);
}
 javac -h . HelloWorld.java

CMakeLists.txt

set(CMAKE_C_STANDARD 11)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(JAVA_AWT_LIBRARY "/root/.sdkman/candidates/java/current/lib")
set(JAVA_JVM_LIBRARY "/root/.sdkman/candidates/java/current/lib/server")
set(JAVA_INCLUDE_PATH "/root/.sdkman/candidates/java/current/include")
set(JAVA_INCLUDE_PATH2 "/root/.sdkman/candidates/java/current/include/linux")
set(JAVA_AWT_INCLUDE_PATH "/root/.sdkman/candidates/java/current/include")

find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})

add_library(hello SHARED HelloWorld.c)

HelloWorld.h


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    displayHelloWorld
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject, jstring);

/*
 * Class:     HelloWorld
 * Method:    readFile
 * Signature: (Ljava/lang/String;)[B
 */
JNIEXPORT jbyteArray JNICALL Java_HelloWorld_readFile
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

HelloWorld.c

#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>

JNIEXPORT jstring JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj, jstring input) {
    const char *input_str = (*env)->GetStringUTFChars(env, input, 0);
    printf("Received string: %s\n", input_str);

    // Additional string to be appended
    const char *additional_str = ",abc";

    // Allocate memory for the output string
    char *output_str = (char *)malloc(strlen(input_str) + strlen(additional_str) + 1);

    // Concatenate input string and additional string
    strcpy(output_str, input_str);
    strcat(output_str, additional_str);

    // Release the input string memory
    (*env)->ReleaseStringUTFChars(env, input, input_str);

    // Create a new Java String from the output string
    jstring result = (*env)->NewStringUTF(env, output_str);

    // Free the memory allocated for the output string
    free(output_str);

    return result;
}

JNIEXPORT jbyteArray JNICALL Java_HelloWorld_readFile(JNIEnv *env, jobject obj, jstring input) {
    const char *input_file = (*env)->GetStringUTFChars(env, input, 0);
    FILE *file = fopen(input_file, "rb");

    if (file == NULL) {
        printf("Error: Unable to open file %s\n", input_file);
        (*env)->ReleaseStringUTFChars(env, input, input_file);
        return NULL;
    }

    // Get the file size
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    // Allocate memory for the file content
    unsigned char *file_content = (unsigned char *)malloc(file_size);

    // Read the file content into memory
    size_t bytes_read = fread(file_content, 1, file_size, file);
    fclose(file);

    // Release the input string memory
    (*env)->ReleaseStringUTFChars(env, input, input_file);

    if (bytes_read != file_size) {
        printf("Error: Unable to read the entire file %s\n", input_file);
        free(file_content);
        return NULL;
    }

    // Create a new Java byte array and copy the file content into it
    jbyteArray result = (*env)->NewByteArray(env, file_size);
    (*env)->SetByteArrayRegion(env, result, 0, file_size, (jbyte *)file_content);

    // Free the memory allocated for the file content
    free(file_content);

    return result;
}
gcc -shared -fPIC -o libhello.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux HelloWorld.c

copy to java path


javac HelloWorld.java         # 重新编译
java -Djava.library.path=. HelloWorld

posted @ 2023-04-19 01:11  张保维  阅读(12)  评论(0编辑  收藏  举报