跨平臺的JAVA調不跨平臺的C--(JNI在Win32&&Linux下的使用)
由于java程序需要調用C或C++的代碼,不得不使用JNI。C的代碼在Win32和Linux下都有相同功能的不同實現(xiàn),就像JDK分幾種平臺版本(win32,linux,solaris等)。首先,看一看首先,看一看win32下調用dll文件。
1, 新建HelloWorld.java
1
public class HelloWorld
2

{
3
static
4
{
5
try
6
{
7
//此處即為本地方法所在鏈接庫名
8
System.loadLibrary("HelloWorld");
9
}catch(UnsatisfiedLinkError e)
{
10
System.err.println( "不能加載dll文件:\n " +e.toString() );
11
}
12
}//end static
13
public native void SayHello(String strName);
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
/**//* DO NOT EDIT THIS FILE - it is machine generated */
2
#include <jni.h>
3
/**//* Header for class HelloWorld */
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
JNIEXPORT void JNICALL Java_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 JNICALL Java_HelloWorld_SayHello (JNIEnv * env, jobject arg, jstring instring)
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 WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
16

{
17
return TRUE ;
18
}
5, 在vc6下新建dll工程HelloWorld,加載HelloWorld.h和HelloWorld.cpp,編譯生成HelloWorld.dll文件,最關鍵的是引用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(String args[])
{
3
HelloWorld hw = new HelloWorld();
4
hw.SayHello("Christmas");
5
}
6
}



2



3

4

5

6

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


再執(zhí)行,ok了,輸出正確結果!
最后,總結一下:
jni的使用很簡單,麻煩的是抽象出所調用dll或so文件的接口封裝成native方法。另外就是生成so或dll文件以后的路徑很不好控制。最重要的一點Java 的C調用通常不能移植到其他平臺上,失去了“write once,run anywhere ”的美譽!但沒違反重用性的規(guī)則。再者,需求來了,不這樣實現(xiàn)能行嗎?
posted on 2005-12-21 18:54 beyondduke 閱讀(1839) 評論(0) 編輯 收藏 所屬分類: 編程隨筆