Java Native Interface(JNI)小記

看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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容