欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

怎么在Java中調(diào)用C/C++本地庫

本篇內(nèi)容介紹了“怎么在Java中調(diào)用C/C++本地庫”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)主營城關(guān)網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,app軟件開發(fā)公司,城關(guān)h5微信小程序開發(fā)搭建,城關(guān)網(wǎng)站營銷推廣歡迎城關(guān)等地區(qū)企業(yè)咨詢

編寫Java類

我們來編寫一個Sample1的java類

public class Sample1 {      public native int intMethod(int n);      public native boolean booleanMethod(boolean bool);      public native String stringMethod(String text);      public native int intArrayMethod(int[] intArray);             public static void main(String[] args) {          System.loadLibrary("Sample1");          Sample1 sample = new Sample1();          int square = sample.intMethod(5);          boolean bool = sample.booleanMethod(true);          String text = sample.stringMethod("Java");          int sum = sample.intArrayMethod(new int[]{1,2,3,4,5,8,13});                     System.out.println("intMethod: " + square);          System.out.println("booleanMethod: " + bool);          System.out.println("stringMethod: " + text);          System.out.println("intArrayMethod: " + sum);      }  }

上面有4個native方法, 分別是4種類型的參數(shù), int, boolean, String, int[].

其中有一句比較重要, 這句話加載了動態(tài)類庫

System.loadLibrary("Sample1");

在windows下加載的就是Sample1.dll, 在linux下加載的就是Sample1.so。

本文使用的windowws, 所以后面使用Sample1.dll來表示Sample1動態(tài)鏈接庫。

注意:不可以在代碼中寫上后綴dll或so. 還要保證Sample1.dll在path路徑中. 這個Sample1.dll是我們后面需要編譯出來的東西。

4個native方法就是我們需要用C來實現(xiàn)的方法。

編譯Sample1.java, 使用命令行(windows是cmd, linux下一般是bash)

>javac Sample1.java

可以看到Sample1.class文件

使用javah生成頭文件

在命令行中運行

>javah Sample1

可以在目錄下看到一個新文件Sample1.h

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h>  /* Header for class Sample1 */    #ifndef _Included_Sample1  #define _Included_Sample1  #ifdef __cplusplus  extern "C" {  #endif  /*   * Class:     Sample1   * Method:    intMethod   * Signature: (I)I   */ JNIEXPORT jint JNICALL Java_Sample1_intMethod    (JNIEnv *, jobject, jint);     /*   * Class:     Sample1   * Method:    booleanMethod   * Signature: (Z)Z   */ JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod    (JNIEnv *, jobject, jboolean);     /*   * Class:     Sample1   * Method:    stringMethod   * Signature: (Ljava/lang/String;)Ljava/lang/String;   */ JNIEXPORT jstring JNICALL Java_Sample1_stringMethod    (JNIEnv *, jobject, jstring);     /*   * Class:     Sample1   * Method:    intArrayMethod   * Signature: ([I)I   */ JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod    (JNIEnv *, jobject, jintArray);     #ifdef __cplusplus  }  #endif  #endif

我們可以看到其中有四個函數(shù)聲明, Java_完整類名_方法名, 完整類名包括了包名, 例如demo.Sample1是完整類名, 對應(yīng)的這里就是demo_Sample1.

在注釋中我們可以看到這樣一個東西 Signature, 這個是方法的簽名. 關(guān)于Signature, 下面通過一個表格來說明。

java類型Signature備注
booleanZ 
byteB 
charC 
shortS 
intI 
longL 
floatF 
doubleD 
voidV 
objectL用/分割的完整類名例如: Ljava/lang/String表示String類型
Array[簽名例如: [I表示int數(shù)組, [Ljava/lang/String表示String數(shù)組
Method(參數(shù)簽名)返回類型簽名例如: ([I)I表示參數(shù)類型為int數(shù)組, 返回int類型的方法

上面頭文件的***個函數(shù)聲明

JNIEXPORT jint JNICALL Java_Sample1_intMethod (JNIEnv *, jobject, jint);

注釋中的簽名是 Signature: (I)I

在每個函數(shù)的參數(shù)列表中都有JNIEnv *和 jobject兩個參數(shù), 這兩個參數(shù)稍候說明。

實現(xiàn)頭文件中的函數(shù)

可以使用C語言來實現(xiàn), 也可以使用C++來實現(xiàn), 下面先說說C語言的實現(xiàn)。

#include "Sample1.h" #include <string.h>     JNIEXPORT jint JNICALL Java_Sample1_intMethod    (JNIEnv *env, jobject obj, jint num)  {      return num * num;  }     JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod    (JNIEnv *env, jobject obj, jboolean boolean)  {      return !boolean;  }     JNIEXPORT jstring JNICALL Java_Sample1_stringMethod    (JNIEnv *env, jobject obj, jstring string)  {      const char* str = (*env)->GetStringUTFChars(env, string, 0);      char cap[128];      strcpy(cap, str);      (*env)->ReleaseStringUTFChars(env, string, 0);      return (*env)->NewStringUTF(env, strupr(cap));  }     JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod    (JNIEnv *env, jobject obj, jintArray array)  {      int i, sum = 0;      jsize len = (*env)->GetArrayLength(env, array);      jint *body = (*env)->GetIntArrayElements(env, array, 0);             for (i = 0; i < len; ++i)      {          sum += body[i];      }      (*env)->ReleaseIntArrayElements(env, array, body, 0);      return sum;  }

(*env)->GetStringUTFChars()這個方法, 是用來在Java和C之間轉(zhuǎn)換字符串的, 因為Java本身都使用了雙字節(jié)的字符, 而C語言本身都是單字節(jié)的字符, 所以需要進行轉(zhuǎn)換.

JNIEnv *是每個函數(shù)都有的參數(shù), 它包含了很多有用的方法, 使用起來類似Java的反射, 也提供了這樣一個編碼轉(zhuǎn)換的函數(shù).

GetStringUTFChars()和NewStringUTF(), ***個是從UTF8轉(zhuǎn)換為C的編碼格式, 第二個是根據(jù)C的字符串返回一個UTF8字符串.

ReleaseStringUTFChars()是用來釋放對象的, 在Java中有虛擬機進行垃圾回收, 但是在C語言中, 這些對象必須手動回收. 否則可能造成內(nèi)存泄漏.

函數(shù)的名字一眼看到就可以猜出功能, jni.h中的大部分函數(shù)名都是這樣.

如果是C++的話, 這段代碼該怎么寫?

下面是C++的代碼

#include "Sample1.h"  #include <string.h>     JNIEXPORT jint JNICALL Java_Sample1_intMethod    (JNIEnv *env, jobject obj, jint num)  {      return num * num;  }     JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod    (JNIEnv *env, jobject obj, jboolean boolean)  {      return !boolean;  }     JNIEXPORT jstring JNICALL Java_Sample1_stringMethod    (JNIEnv *env, jobject obj, jstring string)  {      const char* str = env->GetStringUTFChars(string, 0);      char cap[128];      strcpy(cap, str);      env->ReleaseStringUTFChars(string, 0);      return env->NewStringUTF(strupr(cap));  }     JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod    (JNIEnv *env, jobject obj, jintArray array)  {      int i, sum = 0;      jsize len = env->GetArrayLength(array);      jint *body = env->GetIntArrayElements(array, 0);             for (i = 0; i < len; ++i)      {          sum += body[i];      }      env->ReleaseIntArrayElements(array, body, 0);      return sum;  }

上述兩端代碼非常相似, 只有一個不同點

C代碼: (*env)->GetStringUTFChars(env, string, 0);

C++代碼: env->GetStringUTFChars(string, 0);

C語言中使用的是結(jié)構(gòu)體的函數(shù)指針, 而在C++中使用的還是struct, 我們知道struct在C++中和class的功能是幾乎一樣的, struct也可以用來定義類, 所以env在C++中是個類對象的指針.

編譯和運行

這里使用的是微軟編譯器, 編譯C語言版的dll

>cl -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -LD Sample1.c -FeSample1.dll

編譯C++版本的dll

>cl -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -LD Sample1.cpp -FeSample1.dll

運行

>java Sample1

注意: 64位版本的JDK可能會在運行時報錯:

java.lang.UnsatisfiedLinkError: ...Sample1.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform

如果您有這樣的錯誤, 請使用32位的JDK來重新運行.

運行結(jié)果如下:

intMethod: 25 
booleanMethod: false 
stringMethod: JAVA 
intArrayMethod: 36

“怎么在Java中調(diào)用C/C++本地庫”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

網(wǎng)站欄目:怎么在Java中調(diào)用C/C++本地庫
轉(zhuǎn)載來于:http://aaarwkj.com/article18/igipgp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、營銷型網(wǎng)站建設(shè)、微信公眾號、自適應(yīng)網(wǎng)站網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司
黄色三级视频久久久| 亚洲日本成人一区二区| 国产精品一区二区三区乱色| 日韩精品不卡在线观看| 国产精品久久久久精品综合| 麻豆国产原创av色哟哟| 加藤桃香中文字幕在线| 欧美亚洲一区二区三区91| 麻豆人妻少妇精品系列| 欧美十八一区二区三区| 亚洲一区二区精品免费视频| 国产一区二区91精品| 国产极白丝白浆日本国产| 熟女高潮av一区二区| 亚洲无线码一区国产欧美国日| 国产精品传媒成人免费| 欧美 日本国产一区| 亚洲国产精品一区性色| 一区二区三区日韩专区| 在线最新亚洲日本韩国| 国产在线视频不卡一线路| 精品国内日本一区二区| 日韩天堂视频在线播放| 美女午夜福利精品视频| 国产精品伊人久久精品| 国产成人综合久久二区| 亚洲国产精品欧美激情| 放荡精品少妇一区二区三区| 日本视频免费一区二区| 精品国产av一区二区麻豆| 国语对白视频在线观看| 国产精品高清另类一区二区三区| 欧美乱码中文字幕在线观看 | 国产精品成人av在线| 日韩中文字幕 在线播放| 美女丝袜诱惑国产91| 人妻av在线中文字幕| 99久久精品人妻一区| 国产高清av免费在线观看| 久久久久四虎国产精品| 亚洲久久精品中文字幕|