2. JNI in Eclipse

Step 1: Create a Java Project

Create a new Java project (says HelloJNI), and the following Java class "HelloJNI.java":

public class HelloJNI {
   static {
      System.loadLibrary("hello"); // hello.dll (Windows) or libhello.so (Unixes)
   }
 
   // Declare native method
   private native void sayHello();
 
   // Test Driver
   public static void main(String[] args) {
      new HelloJNI().sayHello();  // invoke the native method
   }
}

Step 2: Convert the Java Project to C/C++ Makefile Project

Right-click on the "HelloJNI" Java project ⇒ New ⇒ Other... ⇒ Convert to a C/C++ Project (Adds C/C++ Nature) ⇒ Next.
The "Convert to a C/C++ Project" dialog appears. In "Project type", select "Makefile Project" ⇒ In "Toolchains", select "MinGW GCC" ⇒ Finish.
Now, you can run this project as a Java as well as C/C++ project.

Step 3: Generate C/C++ Header File

Create a directroy called "jni" under the project to keep all the C/C++ codes, by right-click on the project ⇒ New ⇒ Folder ⇒ In "Folder name", enter "jni".
Create a "makefile" under the "jni" directory, by right-click on the "jni" folder ⇒ new ⇒ File ⇒ In "File name", enter "makefile" ⇒ Enter the following codes. Take note that you need to use tab (instead of spaces) for the indent.

# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

# $* matches the target filename without the extension
HelloJNI.h : HelloJNI.class
    javah -classpath $(CLASS_PATH) $*

This makefile create a target "HelloJNI.h", which has a dependency "HelloJNI.class", and invokes the javah utiltiy on HelloJNI.class (under -classpath) to build the target header file.
Right-click on the makefile ⇒ Make Targets ⇒ Create ⇒ In "Target Name", enter "HelloJNI.h".
Run the makefile for the target "HelloJNI.h", by right-click on the makefile ⇒ Make Targets ⇒ Build ⇒ Select the target "HelloJNI.h" ⇒ Build. The header file "HelloJNI.h" shall be generated in the "jni" directory. Refresh (F5) if necessary. The outputs are:
make HelloJNI.h
javah -classpath ../bin HelloJNI

Step 4: C Implementation - HelloJNI.c

如何查找apt安装的文件安装路径?


2. JNI in Eclipse_第1张图片
有图有真相
which java
ls -lrt /usr/bin/java
ls -lrt /etc/alternatives/java
cd /usr/lib/jvm
ls

其中,/usr/lib/jvm/java-8-oracle/include表示头文件jni.h的所在路径,/usr/lib/jvm/java-8-oracle/include/linux表示头文件jni_md.h所在的路径,/usr/lib/jvm/java-8-oracle表示JDK的安装目录

target 已经建立了怎么办?right click--》build--》remove。
又有其他问题了。
--add-stdcall-alias是[minGW]特有的,删除。
还是不对
所以,看一下makefile到底是什么东西
target 相当于一个命令,build相当于执行这个命令。
clean target就是清除HelloJNI.h HelloJNI.o hello.dll,build就可以完成命令。
现在先去学一下makefile。初步学习makefile,回过头来看这个makefile文件。知道makefile文件的意思但是要从头来理清。
makefile的目的就是生产动态库函数。然后,这个java class就可以被调用了。问题是怎么写这个makefile?

  • 在step3中,用了makefile便宜HelloJNI.h。成功的。看看他的语法。
  • CLASSPATH=.:/bin 设置环境变量CLASSPATH的值为当前目录及/bin目录及/bin目录。 =号后面的 . 是指当前目录,:是分割符号,/bin是指根目录下的bin目录
  • $cd ../bin是到上级目录的bin文件夹下.
  • linux中PATH=$PATH:$HOME/bin是什么意思: 1. ":"代表分隔符. 2. [PATH]=$[PATH]:$[HOME]/[bin]代表在PATH环境变量中增加 $[HOME]/[bin] 这个目录

综上,CLASS_PATH = ../bin set CLASS_PATH = 上级目录的bin文件夹下. 那我就可以推测,指的是HelloJNI.class文件,因为bin里面只有这个文件。是输入文件。

CLASS_PATH = ../bin //上级目录的bin文件夹下
vpath %.class $(CLASS_PATH) //指定.class类型文件的搜索路径是 $(CLASS_PATH)就是../bin
HelloJNI.h : HelloJNI.class
    javah -classpath $(CLASS_PATH) $*
HelloJNI.h : HelloJNI.class
    javah -classpath $(CLASS_PATH) $*
//指的是一条规则,目标是HelloJNI.h文件,依赖是HelloJNI.class文件。命令是`javah -classpath $(CLASS_PATH) $*`。 
//`javah` 是制作头文件的命令,`-classpath`是设置路径的参数,后面跟路径,所以`$(CLASS_PATH) $*`代表路径和具体的依赖名。
//我觉得`$(CLASS_PATH)`表示路径,就相当于`../bin`,`$*`表示去掉后缀".class"的所有文件。

Java中-classpath和路径的使用
javac:如果当前你要编译的Java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上-classpath参数,通过使用以下三种类型的方法 来指导编译器在编译的时候去指定的路径下查找引用类。
(1).绝对路径:javac -classpath c:/junit3.8.1/junit.jar Xxx.java
(2).相对路径:javac -classpath ../junit3.8.1/Junit.javr Xxx.java
(3).系统变量:javac -classpath %CLASSPATH% Xxx.java (注意:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设Junit.jar的路径就包含在CLASSPATH系统变量中)

  • 在step4中,要求修改makefile文件,来生成一个共享的dll库函数。在Linux下,应该是so文件。website
    红色表示要修改的地方。如下:
all : hello.dll
 # $@ matches the target, $< matches the first dependancy
hello.dll : HelloJNI.o
    gcc -Wl,--add-stdcall-alias -shared -o $@ $<
 # $@ matches the target, $< matches the first dependancy
HelloJNI.o : HelloJNI.c HelloJNI.h
    gcc -I"D:\bin\jdk1.7\include" -I"D:\bin\jdk1.7\include\win32" -c $< -o $@
clean :
    rm HelloJNI.h HelloJNI.o hello.dll #最简单,没有依赖,目标不是文件是空置(状态),命令是rm就是删除,注意。dll应改为so。
  1. “libhello.so”
  2. “#”表示注释
 # Define a variable for classpath
CLASS_PATH = ../bin
 # Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : libhello.so

# $@ matches the target, $< matches the first dependancy
libhello.so : HelloJNI.o
    gcc -o libhello.so -shared HelloJNI.o

# $@ matches the target, $< matches the first dependancy
HelloJNI.o : HelloJNI.c HelloJNI.h
    gcc -fpic -I/usr/lib/jvm/java-8-oracle/include -I/usr/lib/jvm/java-8-oracle/include/linux -c HelloJNI.c -o $@
# $* matches the target filename without the extension
HelloJNI.h : HelloJNI.class
    javah -classpath $(CLASS_PATH) $*

clean :
    rm HelloJNI.h HelloJNI.o libhello.so

step 5 Run the Java JNI Program

  • You can run the Java JNI program HelloJNI. However, you need to provide the library path to the "hello.dll". This can be done via VM argument -Djava.library.path.
  • Right-click on the project ⇒ Run As ⇒ Run Configurations ⇒ Select "Java Application"(双击new) ⇒ In "Main" tab, enter the main class "HelloJNI" ⇒ In "Arguments", "VM Arguments", enter "-Djava.library.path=jni" ⇒ Run.
  • You shall see the output "Hello World!" displayed on the console.


    2. JNI in Eclipse_第2张图片
    Hello World!
  1. ECLIPSE CDT & JNI (JAVA NATIVE INTERFACE) WITH 64 BIT MINGW - 2017
  2. 轻松使用Eclipse CDT进行Java JNI编程

end

你可能感兴趣的:(2. JNI in Eclipse)