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安装的文件安装路径?


有图有真相
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。成功的。看看他的语法。

综上,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.


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

end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容