看JAVA源碼的時(shí)候發(fā)現(xiàn)很多類使用到native關(guān)鍵字,查了下發(fā)現(xiàn)跟C#的import作用差不多,就是用來(lái)調(diào)用動(dòng)態(tài)鏈接庫(kù)dll文件方法的關(guān)鍵字。
自己試試才更好理解,以下是我折騰這個(gè)的過(guò)程:
一:
先用JAVA寫好一個(gè)調(diào)用類(就當(dāng)這個(gè)DLL已經(jīng)存在了)。
packageorg.uroot.jni;
/**
* Created by Sealin on 2017-12-06.
* http://java.uroot.org/
*/
public classHelloJNI {
public native voidsay();
static{
//這里引用名要和生成的DLL文件名一致,引用的時(shí)候不寫.dll
System.loadLibrary("org_uroot_jni_HelloJNImpl");
}
public static voidmain(String[] args) {
HelloJNI jni =newHelloJNI();
jni.say();
}
}
二:編譯這個(gè)類,生成.class文件
javac org.uroot.jni.HelloJNI
三:使用javah生成這個(gè)class文件的*.h文件(C語(yǔ)言的頭文件),我生成的文件名是【org_uroot_jni_HelloJNI.h】
javah -jni HelloJNI
如果一切正常,那*.h文件已經(jīng)生成在當(dāng)前目錄了。這個(gè)文件一般不要去修改它,因?yàn)樗闪藢?duì)應(yīng)class文件的結(jié)構(gòu)和調(diào)用方法的引用等信息,和JAVA文件中的say方法結(jié)構(gòu),結(jié)構(gòu)如下:
JAVA_完整包路徑_類名_方法名
//比如我這個(gè)示例生成的.h抽象方法名是:
Java_org_uroot_jni_HelloJNI_say (JNIEnv *, jobject);
四:新建一個(gè)c或者cpp文件,這里叫【org_uroot_jni_HelloJNImpl.cpp】,引入生成的頭文件,并實(shí)現(xiàn)上述頭文件的方法部分
#include "org_uroot_jni_HelloJNI.h"
#include
#include "jni.h"
#include "stdafx.h"
/**
*Class: org_uroot_jni_HelloJNI
* Method: say
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_uroot_jni_HelloJNI_say
(JNIEnv *, jobject) {
printf("Hello, I'm Java Native Interface\n");
return;
}
void main() {
Java_org_uroot_jni_HelloJNI_say(nullptr, NULL);
}
五:把【%JAVA_HOME%\include\jni.h】和【%JAVA_HOME%\include\win32\jni_md.h】放到當(dāng)前文件夾,編譯【org_uroot_jni_HelloJNImpl.cpp】,我這里因?yàn)檠b了VS,所以直接用cl工具進(jìn)行DLL編譯
cl /LD org_uroot_jni_HelloJNImpl.cpp
我在這里弄了好久,因?yàn)橐恢碧崾菊也坏絡(luò)ni.h,打開javah生成的頭文件看了下,發(fā)現(xiàn)生成的引入方式是#include ,因?yàn)樵趐ath環(huán)境變量里邊沒有加入include和include/win32,所以導(dǎo)致了這個(gè)問題,將我們生成的頭文件和新建的實(shí)現(xiàn)文件此處引用都改為【 #include "jni.h"】,編譯通過(guò)。
六:確認(rèn).class和剛剛生成的.dll都在同一個(gè)目錄中后,就可以運(yùn)行試試效果了
java org.uroot.jni.HelloJNI
這里加入包名后可能會(huì)出現(xiàn)無(wú)法找到DLL的情況,確認(rèn)引用名和DLL文件名一樣后還是說(shuō)找不到,但是寫java文件的時(shí)候不使用包就不存在這個(gè)問題,到網(wǎng)上查了下,程序在執(zhí)行的時(shí)候會(huì)在PATH環(huán)境變量中去查找引用DLL,所以加入了個(gè)文件夾到系統(tǒng)PATH,然后把剛剛生成的DLL文件放到里邊,再執(zhí)行就可以了
_>java org.uroot.jni.HelloJNI
_>Hello, I'm Java Native Interface