出自:http://wenku.baidu.com/link?url=X_plf2x-5OL9FOhLoGtA6JjfS5ivKKFF7m7fvwdnL0vWxi4Ulr-tZCS1UZ_ml20-sVYWwqXE4qcxAeWS7v-kCi5lpZ3ku9qxaoStoVmMeVShtml
JNI入門教程之HelloWorld篇java
資料引用:http://www.knowsky.com/363050.htmlc++
本文講述如何使用JNI技術實現HelloWorld,目的是讓讀者熟悉JNI的機制並編寫第一個HelloWorld程序。編程
Java Native Interface(JNI)是Java語言的本地編程接口,是J2SDK的一部分。在java程序中,咱們能夠經過JNI實現一些用java工具
語言不便實現的功能。一般有如下幾種狀況咱們須要使用JNI來實現。url
標準的java類庫沒有提供你的應用程序所須要的功能,一般這些功能是平臺相關的你但願使用一些已經有的類庫或者應用程序,而他們並不是用spa
java語言編寫的程序的某些部分對速度要求比較苛刻,你選擇用匯編或者c語言來實現並在java語言中調操作系統
用他們在《java核心技術》中,做者提到JNI的時候,建議不到萬不得已不要使用JNI技術,一方面它須要你把握更多的知識才能夠駕馭,一方面使用了htm
JNI你的程序就會喪失可移植性。在本文咱們跳過JNI的底層機制,讀者最好先把它想象爲本地代碼和java代碼的粘合劑。關係以下圖所示:教程
下面咱們開始編寫HelloWorld程序,因爲涉及到要編寫c/c++代碼所以咱們會在開發中使用Microsoft VC++工具。
編寫java代碼。
咱們在硬盤上創建一個hello目錄做爲咱們的工做目錄,首先咱們須要編寫本身的java代碼,在java代碼中咱們會聲明native方法,代碼很是簡單。以下所示
class HelloWorld{
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
注重咱們的
displayHelloWorld()
方法的聲明,
它有一個要害字
native
,
代表這個方法使用
java
以
外
的
語
言
實
現
。
方
法
不
包
括
實
現
,
因
爲
我
們
要
用
c/c++
語
言
實
現
它
。
注
重
System.loadLibrary("hello")
這句代碼,
它是在靜態初始化塊中定義的,
系統用來裝載
hello
共
享庫,這就是咱們在後面生成的
hello.dll
(假如在其餘的操做系統多是其餘的形式,好比
hello.so
)
編譯
java
代碼
javac HelloWorld.java
生成
HelloWorld.class
文件
建立
.h
文件
這一步中咱們要使用
javah
命令生成
.h
文件,這個文件要在後面的
c/c++
代碼中用到,咱們
運行
javah
HelloWorld
。這樣咱們能夠看到在相同目錄下生成了一個
HelloWorld.h
文件,文件內
容以下
在此咱們不對他進行太多的解釋。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:
HelloWorld
* Method:
displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
編寫本地實現代碼
在這部分咱們要用
C/C++
語言實現
java
中定義的方法,咱們在
VC++
中新建一個
Project,
然
後建立一個
HelloWorldImp.cpp
文件,內容以下
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
注重咱們這裏
include
了
jni.h
和剛纔獲得的
HelloWorld.h
文件。
所以你要在
VC++
裏面設置
好,
jni.h
在
JA
V
A_HOME/include
裏面。編譯經過後再生成
hello.dll
文件。
運行
java
程序
把
上
面
生
成
的
hello.dll
文
件
復
制
到
我
們
的
工
做
目
錄
,
這
時
候
我
們
的
目
錄
中
包
括
HelloWorld.java
,
HelloWorld.class
和
hello.dll
文件。運行
java HelloWorld
命令,則可在控制
臺看到
Hello world
的輸出了。
-
資料引用
:http://www.knowsky.com/363050.html
Java: JNI
徹底手冊時間
:2007-02-10 00:00:00
來源
:
做者
:
最近在公司裏作了一個手機的項目,
須要
JA
V
A
程序在發送短信的時候和第三方的短信服務
器鏈接。
短信接口是用
C++
寫的。
琢磨了三天,
大體搞懂了
JNI
的主體部分。
先將心得整理,
但願各位朋友少走彎路。
首先引用一篇文章,介紹一個簡單的
JNI
的調用的過程。
JA
V
A
以其跨平臺的特性深受人們喜好,而又正因爲它的跨平臺的目的,使得它和本地機器
的各類內部聯繫變得不多,約束了它的功能。解決
JA
V
A
對本地操做的一種方法就是
JNI
。
JA
V
A
經過
JNI
調用本地方法,
而本地方法是以庫文件的形式存放的
(在
WINDOWS
平臺上
是
DLL
文件形式,在
UNIX
機器上是
SO
文件形式)
。經過調用本地的庫文件的內部方法,
使
JA
V
A
能夠實現和本地機器的緊密聯繫,調用系統級的各接口方法。
簡單介紹及應用以下:
1、
JA
V
A
中所須要作的工做
在
JA
V
A
程序中,首先須要在類中聲明所調用的庫名稱,以下:
static {
System.loadLibrary(「goodluck」);
}
在這裏,庫的擴展名字能夠不用寫出來,到底是
DLL
仍是
SO
,由系統本身判斷。
還需對將要調用的方法作本地聲明,關鍵字爲
native
。且只須要聲明,而不須要具體實現。
以下:
public native static void set(int i);
public native static int get();
而後編譯該
JA
V
A
程序文件,生成
CLASS
,再用
JA
V
AH
命令,
JNI
就會生成
C/C++
的頭文
件。
例如程序
testdll.java
,內容爲:
public class testdll
{
static
{
System.loadLibrary(\"goodluck\");
}
public native static int get();
public native static void set(int i);
public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}
用
javac testdll.java
編譯它,會生成
testdll.class
。
再用
javah testdll
,
則會在當前目錄下生成
testdll.h
文件,
這個文件須要被
C/C++
程序調用來
生成所需的庫文件。
2、
C/C++
中所須要作的工做
對於已生成的
.h
頭文件,
C/C++
所須要作的,就是把它的各個方法具體的實現。而後編譯連
接成庫文件便可。再把庫文件拷貝到
JA
V
A
程序的路徑下面,就能夠用
JA
V
A
調用
C/C++
所
實現的功能了。
接上例子。咱們先看一下
testdll.h
文件的內容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class testdll */
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern \"C\" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
/*
* Class: testdll