JNI基本操作
目的
本文為JNI HelloWorld教程狮崩,闡述編寫java本地調(diào)用的一般方法流程扎拣,可用于pmdk的API調(diào)用孤澎。
環(huán)境準備
- vim 或其他IDE
- Linux運行環(huán)境包含gcc
- JDK 8
簡單來說涵妥,是臺Linux機器都行进统,裝過Insight的機器都有JDK環(huán)境
流程
Java端代碼
先看下普通的HelloWorld
創(chuàng)建文件 HelloWorld.java(文件名需與類名一致)
public class HelloWorld {
public void sayHello(String message) {
System.out.println(message);
}
public static void main(String []args) {
new HelloWorld().sayHello("Hello World");
}
}
- JNI版本的HelloWorld
創(chuàng)建文件 JNIDemo.java(文件名需與類名一致)
public class JNIDemo {
//定義一個方法沈堡,該方法在C中實現(xiàn)
public native void sayHelloC();
public static void main(String[] args) {
System.loadLibrary("testJNI");
JNIDemo jniDemo = new JNIDemo();
jniDemo.sayHelloC();
}
}
- 利用此java類生成c頭文件
javah -classpath . -jni com.insight.test.JNIDemo
如果沒有寫package則執(zhí)行(像本文所述就沒寫包名):
javah -classpath . -jni JNIDemo
可見生成對應(yīng)的頭文件静陈。
native代碼
- 編寫c/c++文件
#include "JNIDemo.h"
#include <iostream>
#include <stdio.h>
JNIEXPORT void JNICALL Java_com_insight_test_JNIDemo_sayHelloC
(JNIEnv *, jobject) {
printf("Hi,this is C++ print! \n");
}
注意了,"JNIDemo.h
"就是第2步生成的那個頭文件,與c代碼放在同一目錄下鲸拥。
- 編譯生成動態(tài)鏈接庫
生成.o
文件的話執(zhí)行:g++ -c testJNI.cpp
(僅記錄一下拐格,不需要執(zhí)行這一個操作!)
生成動態(tài)庫.so文件:(copy這個↓↓)
g++ -shared testJNI.cpp -o libtestJNI.so -fPIC
如果未指定-o參數(shù), 則默認生成的庫文件是a.out
- (可選)將libtestJNI.so拷貝到庫路徑下刑赶,如
/usr/lib64
- 運行Java類
java -cp . com.insight.test.JNIDemo
,在根目錄執(zhí)行,可以看到輸出為cpp文件所定義的方法內(nèi)容捏浊。
“Hi,this is C++ print!”:heart:
OK了 :smile:撞叨。
Debug
Q:運行Java程序報錯:Error:Could not find or load main class XXXX金踪。如何解決?
A:代碼HelloWorld級別都不能運行成功牵敷,不是代碼的問題胡岔。
檢查對比可運行的環(huán)境得知,出錯的機器包含了CLASSPATH變量枷餐,該環(huán)境變量指向JAVA_HOME/lib怨咪。
正常運行的環(huán)境里沒有設(shè)置這個變量润匙,因此執(zhí)行unset CLASSPATH
java ClassName
即可正常執(zhí)行!肄鸽!
Q:報錯缺少jni.h,jni_md.h,或找不到蟀苛?
A: 不要使用拷貝該文件的方式,配置CPATH環(huán)境變量來實現(xiàn)裆甩。
Q: 有package的類怎么直接編寫執(zhí)行?
A:按包名層級創(chuàng)建文件夾叨叙,把類文件放進去。執(zhí)行時需要到根目錄钮呀,執(zhí)行java -cp . com.insight.test.JNIDemo
,這樣可包含類路徑。否則出現(xiàn)Error: Could not find or load main class com.insight.test.JNIDemo
Q: 怎么編譯動態(tài)鏈接庫.so文件或.o文件?
A: 見流程4证杭。結(jié)尾.o的文件不是必須要有的。
點:Java本地調(diào)用、JNI入門
線:Java
面:編程技術(shù)