日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

JNI设置C++与java的结合(2)

發(fā)布時間:2025/4/16 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JNI设置C++与java的结合(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

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

java類型

Signature

備注

boolean

Z


byte

B


char

C


short

S


int

I


long

L


float

F


double

D


void

V


object

L/分割的完整類名

例如: 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).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#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()這個方法,?是用來在JavaC之間轉換字符串的,?因為Java本身都使用了雙字節(jié)的字符,?C語言本身都是單字節(jié)的字符,?所以需要進行轉換.

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

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

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

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

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

下面是C++的代碼

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#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語言中使用的是結構體的函數(shù)指針,?而在C++中使用的還是struct,?我們知道structC++中和class的功能是幾乎一樣的, struct也可以用來定義類,?所以envC++中是個類對象的指針.

編譯和運行

這里使用的是微軟編譯器,?編譯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來重新運行.

運行結果如下:

intMethod: 25

booleanMethod: false

stringMethod: JAVA

intArrayMethod: 36

?源代碼下載:?Sample1.zip

運行其中的build&run.bat文件即可,?如有錯誤請根據(jù)實際情況修改其中的一些參數(shù).

DLL工程文件VC6.0VS2010:?VC6.0&VS2010.zip

參考文獻:

  • Scott Stricker,??JNI?進行?Java?編程, ? ? ?http://www.ibm.com/developerworks/cn/education/java/j-jni/section2.html

  • JDK 6u30 docs, Java Native ? ? ?Interface Specification, Chapter 3 JNI Types and Data Structures, Type ? ? ?Signatures.

  • 總結

    以上是生活随笔為你收集整理的JNI设置C++与java的结合(2)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。