JNI-use Java to call C program

Now there is a need to use Java to call the system API of linux or windows, or a local method that requires C language to implement. At this time, JNI came out.

See a complete example below:

Preparation: Install mingw-64 compiler under windows and compile  with gcc command

First, create a Java class file

Main.java

public class Main {
    // 静态初始化代码块,保证虚拟机在第一次使用该类时就会装载库
    static{
        System.loadLibrary("MyNativeLib");
    }

    // native 关键字表示本地方法,提醒编译器该方法将在外部定义(注:不能包含_)
    public static native void sayHello();

    // 主函数调用本地方法
    public static void main(String[] args) {
        sayHello();
    }
}

Second, generate the .h header file

> javac Main.java
> javah -classpath . -jni Main

The contents of the Main.h file generated using the above command are as follows:

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

#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Main
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Main_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Three, create a C implementation file

Create the Main.c file to implement the functions in the header file.

#include <stdio.h>
#include "Main.h"

JNIEXPORT void JNICALL Java_Main_sayHello(JNIEnv *env, jobject c1) {
	printf("Hello Native !!\n");
}

Fourth, compile and generate dynamic link library

Use gcc's -I parameter (uppercase i) to specify the directory where the header file needs to be found.

Or, copy include / jni.h and include / win32 / jni_md.h under the JDK directory to the current project directory.

Then execute the command (before you need to change #include <jni.h> in Main.h to #include "jni.h", search for the header file in the current directory first, and then search in the system directory)

> gcc -fPIC -shared -o MyNativeLib.dll Main.c

The MyNativeLib.dll dynamic link library file has been generated in this directory, and other C language files can be deleted.

Five, test operation

> java Main

The running result is:

 

common problem:

  • java.lang.UnsatisfiedLinkError: class name. function name () V

At this time, the dynamic library has been loaded, check whether the function name of the .h file and the .c file are consistent, and the name cannot be underlined _.

The function names in the c file are regular Java_Main_sayHello, Java_class name_function name.

  • no MyNativeLib in java.library.path at java.lang.ClassLoader.loadLibrary(Unknown Source)

If none of the dll libraries are loaded successfully, see if the corresponding dll is successfully generated, whether the compile command is correct and the project location, etc.

  • Compiled in Linux environment is the same as above, the dynamic library file extension is .so

reference:

Published 19 original articles · won praise 9 · views 2996

Guess you like

Origin blog.csdn.net/Necrolic/article/details/105542898