<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ? ? ? ? JNI其實是Java NativeInterface的簡稱,也就是java本地接口。它提供了若干的API實現了和Java和其他語言的通信(主要是C/C++)。 ? ? ? ? Java以其跨平臺的特性深受人們喜愛,而又正由于它的跨平臺的目的,使得它和本地機器的各種內部聯系變得很少,約束了它的功能。解決Java對本地操作的一種方法就是JNI。 ? ? ? ? Java通過JNI調用本地方法,而本地方法是以庫文件的形式存放的(在WINDOWS平臺上是DLL文件形式,在UNIX機器上是SO文件形式)。通過調用本地的庫文件的內部方法,使JAVA可以實現和本地機器的緊密聯系,調用系統級的各接口方法。 ? ? ? ? 在項目中管理很好一般可以不使用JNI,但是有時候必須用到的時候就要掌握一下這個東西了。其實Java很多的源碼里面的一些算法都是Native聲明的,也就是這些方法很可能是在C/C++中實現了的。 ? ? ? ? 我沒事做的時候自己單獨重新做了一遍JNI使用過程,分享一下流程。 1. 首先在Eclipse建立一個Java類,在這個類中用native關鍵字聲明需要用到的函數 下面是我自己寫的測試代碼 ~~~ package com.ghgame.javausecpp; public class JavaUseCpp { public JavaUseCpp() { System.out.println(">>>>>JNI Test Start<<<<<"); } static { } public native void printStr(String str); } ~~~ 2. 在DOS窗口下生產C++的h文件 ? ?這里使用命令來完成 ? ?去找到Eclipse新建的工程目錄下的bin文件夾,bin存放編譯好的class文件; ? ?然后cd 到這個E:\WorkAndroid\JNITest\bin目錄 ? ?在dos下輸入命令 ? ?E:\WorkAndroid\JNITest\bin>javah-classpath . -jni com.ghgame.javausecpp. JavaUseCpp ? ?然后在E:\WorkAndroid\JNITest\bin即可找到一個com_ghgame_javausecpp_JavaUseCpp.h頭文件,生成成功! 注意:com.ghgame.javausecpp是包名,JavaUseCpp是類名 下面是生成的h文件截圖: ![](https://box.kancloud.cn/2016-08-19_57b6ce7bb80e0.jpg) 這里javah的用法: ![](https://box.kancloud.cn/2016-08-19_57b6ce7bcfd2e.jpg) 到這里Java部分就算是差不多了。 可以打開看看剛剛生成的這個**com_ghgame_javausecpp_JavaUseCpp.h**頭文件 ~~~ /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_ghgame_javausecpp_JavaUseCpp */ #ifndef _Included_com_ghgame_javausecpp_JavaUseCpp #define _Included_com_ghgame_javausecpp_JavaUseCpp #ifdef __cplusplus extern "C" { #endif /* * Class: com_ghgame_javausecpp_JavaUseCpp * Method: printStr * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_ghgame_javausecpp_JavaUseCpp_printStr (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif ~~~ ? ? ? 這里面注釋上標注類名、方法名、簽名(Signature),簽名這個東西下面來說。在這里最重要的是Java_com_ghgame_javausecpp_JavaUseCpp_printStr這個方法簽名。在Java端我們執行 printStr(String str)這個方法之后,JVM就會幫我們調用在DLL里的Java_com_ghgame_javausecpp_JavaUseCpp_printStr這個方法。因此我們新建一個C++source file來實現這個方法。 ? ? ? ?還是扯哈簽名這個東西。 ? ? ? ?為什么會有方法簽名這種東西呢?這是因為Java這邊支持函數重載,即雖然參數不一樣,但是方法名一樣,那么在JNI層它們的方法名都會是一樣的,那JNI也會犯迷糊了,得找哪個呢? ? ? ? ?不過也正是因為其參數類型是不一樣的,所以就出現了方法簽名,利用方法簽名和方法名來唯一確定一個JNI函數的調用。 ? ? ? ?既然方法簽名是基于參數類型的不同而形成的,首先要知道Java各數據類型對應的簽名是什么,也就是所謂的類型簽名, 在jni.h文件中就已經定義了這樣一套規則,如下: ~~~ typedef union jvalue { jboolean z; jbyte b; jchar c; jshort s; jint i; jlong j; jfloat f; jdouble d; jobject l; } jvalue; ~~~ 具體不清楚的還是找度娘問其他先生。 3. 寫CPP文件,編譯出DLL ? ?建項目具體步驟就不說了。 ? ?新建一個Win32Cpp就行了,里面選dll,然后把剛才編譯出來的h文件復制到C++工程的根目錄去 ? ?然后新建一個**com_ghgame_javausecpp_JavaUseCpp.cpp**Cpp文件 ? ?在這里面實現h文件中的方法,我這里就打印了一下Java傳過來的值而已 ~~~ #include "stdafx.h" #include "com_ghgame_javausecpp_JavaUseCpp.h" JNIEXPORT void JNICALL Java_com_ghgame_javausecpp_JavaUseCpp_printStr(JNIEnv* env, jobject obj, jstring str) { const char* pTempStr = env->GetStringUTFChars(str, NULL); printf(">>>>>>>>>>>>>>>The input string is = [ %s ]<<<<<<<<<<<<<<",pTempStr); } ~~~ 這里編譯的時候值得注意的幾個問題: a.?需要另外兩個頭文件 ? ?都在jdk的安裝目錄下,有個include文件夾,把include文件夾下面的jni.h復制到C++工程的根目錄,然后把com_ghgame_javausecpp_JavaUseCpp.h文件的#include <jni.h>改成#include "jni.h"就行了。 ? ?還有個在include里面有個win32文件夾,jni_md.h這個頭文件也復制到C++工程的根目錄。 b. 在編譯項目時候要注意選擇平臺,如果你jdk,機子都是64位你就編譯64位的dll,32位同理。否則就是這個錯誤:JNI Can't load IA 32-bit .dll on a AMD 64-bit platform 編譯出來的內容就是這樣: ![](https://box.kancloud.cn/2016-08-19_57b6ce7beca10.jpg) 4. 配置Dll ? ?這里加載的方法有兩個, a. 把剛剛生成的Dll扔到C盤Sysytem32或者SysWOW64文件夾下 b. 把C++工程下生成dll的目錄設置到環境變量path中去(我是64位的機子就把x64的配置到Path去了) ![](https://box.kancloud.cn/2016-08-19_57b6ce7c1a579.jpg) 這個設置看個人喜好了 5. Java加載Dll,完成 到最后一步了,在Java里面加載Dll庫,調用c++實現的方法 ~~~ package com.ghgame.javausecpp; public class JavaUseCpp { public JavaUseCpp() { System.out.println(">>>>>JNI Test Start<<<<<"); } // 加載生成的DLL庫文件 static { System.loadLibrary("LibJniTest"); } public native void printStr(String str); public static void main(String[] args) { String cName = "Ghgame"; // 傳個值試試效果 new JavaUseCpp().printStr(cName); } } ~~~ 下面是我執行的結果: ![](https://box.kancloud.cn/2016-08-19_57b6ce7c4c911.jpg) 感覺還是挺66666的。 好了,GG了,收拾東西準備下班。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看