由于java程序需要調(diào)用C或C++的代碼,不得不使用JNI。C的代碼在Win32和Linux下都有相同功能的不同實現(xiàn),就像JDK分幾種平臺版本(win32,linux,solaris等)。
首先,看一看首先,看一看win32下調(diào)用dll文件。
1, 新建HelloWorld.java
3,在命令行下,javah -jni HelloWorld 生成 HelloWorld.h文件
6,設置classpath為dll文件所在路徑,新建一個測試類TestHelloWorldDLL.java
7,輸出結(jié)果: HelloWorld Christmas
=======================================================================================================
接下來,在linux下調(diào)用so試一試。
因為linux下不能用vc所以gcc,如下命令:
#
gcc-I/usr/java/include-shared-olibHelloWorld.soHelloWorld.cpp
運行測試程序,發(fā)現(xiàn)不能導入.so文件,提示noHelloWorld in java.library.path,所以需要設置java.library.path。
java
-
Djava
.
library
.
path
=
`pwd`
-
cp
.
MyNative
注意我把.so文件拷到了當前路徑,其他路徑設置即可!
再執(zhí)行,ok了,輸出正確結(jié)果!
最后,總結(jié)一下:
jni的使用很簡單,麻煩的是抽象出所調(diào)用dll或so文件的接口封裝成native方法。另外就是生成so或dll文件以后的路徑很不好控制。最重要的一點Java 的C調(diào)用通常不能移植到其他平臺上,失去了“write once,run anywhere ”的美譽!但沒違反重用性的規(guī)則。再者,需求來了,不這樣實現(xiàn)能行嗎?
首先,看一看首先,看一看win32下調(diào)用dll文件。
1, 新建HelloWorld.java
1
public
class
HelloWorld
2
{
3
static
4
{
5
try
6
{
7
//
此處即為本地方法所在鏈接庫名
8
System.loadLibrary(
"
HelloWorld
"
);
9
}
catch
(UnsatisfiedLinkErrore)
{
10
System.err.println(
"
不能加載dll文件:\n
"
+
e.toString());
11
}
12
}
//
endstatic
13
public
native
void
SayHello(StringstrName);
14
15
}
16
2,編譯java文件生成HelloWorld.class文件

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

3,在命令行下,javah -jni HelloWorld 生成 HelloWorld.h文件
1
/*
DONOTEDITTHISFILE-itismachinegenerated
*/
2
#include
<
jni.h
>
3
/*
HeaderforclassHelloWorld
*/
4
5
#ifndef_Included_HelloWorld
6
#define_Included_HelloWorld
7
#ifdef__cplusplus
8
extern"C"{
9
#endif
10
/*
11
*Class:HelloWorld
12
*Method:SayHello
13
*Signature:(Ljava/lang/String;)
14
*/
15
JNIEXPORTvoidJNICALLJava_HelloWorld_SayHello
16
(JNIEnv
*
,jobject,jstring);
17
18
#ifdef__cplusplus
19
}
20
#endif
21
#endif
22
4, 編寫HelloWorld.cpp

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

1
#include
<
windows.h
>
2
#include
"
HelloWorld.h
"
3
#include
<
stdio.h
>
4
//
與Hello.h中函數(shù)聲明相同
5
JNIEXPORT
void
JNICALLJava_HelloWorld_SayHello(JNIEnv
*
env,jobjectarg,jstringinstring)
6
{
7
//
從instring字符串取得指向字符串UTF編碼的指針
8
const
jbyte
*
str
=
9
(
const
jbyte
*
)env
->
GetStringUTFChars(instring,JNI_FALSE);
10
printf(
"
HelloWorld,%s\n
"
,str);
11
//
通知虛擬機本地代碼不再需要通過str訪問Java字符串。
12
env
->
ReleaseStringUTFChars(instring,(
const
char
*
)str);
13
return
;
14
}
15
int
WINAPIDllMain(HINSTANCEhInstance,DWORDfdwReason,PVOIDpvReserved)
16
{
17
return
TRUE;
18
}
5,在vc6下新建dll工程HelloWorld,加載HelloWorld.h和HelloWorld.cpp,編譯生成HelloWorld.dll文件,最關(guān)鍵的是引用JAVAHOME\include\和JAVAHOME\include\win32的.h文件。

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

6,設置classpath為dll文件所在路徑,新建一個測試類TestHelloWorldDLL.java
1
public
class
HelloWorld
{
2
public
static
void
main(Stringargs[])
{
3
HelloWorldhw
=
new
HelloWorld();
4
hw.SayHello(
"
Christmas
"
);
5
}
6
}

2

3

4

5

6

7,輸出結(jié)果: HelloWorld Christmas
=======================================================================================================
接下來,在linux下調(diào)用so試一試。
因為linux下不能用vc所以gcc,如下命令:


再執(zhí)行,ok了,輸出正確結(jié)果!
最后,總結(jié)一下:
jni的使用很簡單,麻煩的是抽象出所調(diào)用dll或so文件的接口封裝成native方法。另外就是生成so或dll文件以后的路徑很不好控制。最重要的一點Java 的C調(diào)用通常不能移植到其他平臺上,失去了“write once,run anywhere ”的美譽!但沒違反重用性的規(guī)則。再者,需求來了,不這樣實現(xiàn)能行嗎?
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
