java 调用本地接口_JAVA通过本地接口调用C++
技術簡介
JNI,全稱java native
interface,是java語言與其他類型語言交互的接口。下圖是Sun站點上對JNI的基本結構的描述。JNI是Java語言的本地編程接口,是J2SDK的一部分。在java程序中,我們可以通過JNI實現(xiàn)一些用java語言不便實現(xiàn)的功能。通常有以下幾種情況我們需要使用JNI來實現(xiàn)。?·標準的java類庫沒有提供你的應用程序所需要的功能,通常這些功能是平臺相關的?·你希望使用一些已經(jīng)有的類庫或者應用程序,而他們并非用java語言編寫的?·程序的某些部分對速度要求比較苛刻,選擇用匯編或者c語言來實現(xiàn)并在java語言中調(diào)用他們
Java中調(diào)用C/C++方法:
1、Native Method Declaration(原生函數(shù)聲明)
原生函數(shù)聲明是Java虛擬機與原生函數(shù)之間的橋梁。同樣可以這樣理解,它是Java虛擬機與本地庫文件之間的接口。在具體運作上,它與普通的Java函數(shù)聲明沒有大的區(qū)別,除了要在函數(shù)聲明前添加native關鍵字。函數(shù)聲明的參數(shù)表應為Java的內(nèi)部類型,有相應的JNI函數(shù)完成Java與其他不同語言之間的數(shù)據(jù)類型轉換。
示例:
native
byte[] loadFile(String name);
2、Load the Library(裝載原生函數(shù)庫)
原生函數(shù)庫文件包含了原生函數(shù)的代碼實現(xiàn),
通過調(diào)用System.loadLibrary進行裝載.通常把它放置在靜態(tài)初始化塊中,以保證每個類只初始化一次,當然這也可以在別的地方.需要注意的是,你需要配置系統(tǒng)的環(huán)境以保證在運行時可以找到要裝載的庫文件.
示例:
static
{
System.loadLibrary("nativelib");
}
3、Complile the Program(編譯程序)
調(diào)用javac編譯java源文件.
示例:
javac
test.java
4、Generate the Header File
調(diào)用javah生成C/C++需要的頭文件.生成頭文件主要內(nèi)容為C/C++語言的原生函數(shù)聲明,它是Java語言與C/C++語言之間的接口.生成的原生函數(shù)聲明來自Java中的原生函數(shù)聲明,但有所不同.新的函數(shù)聲明函數(shù)名字以及參數(shù)名字,均依照jni內(nèi)部規(guī)則生成.需要注意的是:參數(shù)表的第一個總會是JNIEnv
*,虛擬機環(huán)境信息指針;第二個參數(shù)依據(jù)Java中原生函數(shù)聲明不同而不同,靜態(tài)函數(shù)為jclass,非靜態(tài)函數(shù)為jobject.
示例:
javah
test
5、Implement the Native Method(實現(xiàn)原生方法)
包含生成的原生函數(shù)頭文件和jni.h,編寫原生函數(shù)的實現(xiàn).原生函數(shù)內(nèi)容主要為C/C++語言編寫的平臺相關代碼,同時涉及與Java虛擬機之間數(shù)據(jù)的交換.JNI提供了相應的C/C++語言實現(xiàn)的轉換函數(shù),通過傳入JNIEnv
*env給轉換函數(shù)可以完成數(shù)據(jù)轉換.詳情見jni.h
6、Compile the Dynamic or Shared Object Library
編譯C/C++程序,生成動態(tài)鏈接庫,具體操作如下圖所示
7、Run the Example
執(zhí)行Java程序.需要注意,需要保證編譯產(chǎn)生的動態(tài)鏈接庫能夠被正確裝載.下圖是不同操作系統(tǒng)下,指定當前目錄為庫文件目錄的示例.如果指定為你它路徑可仿此例.
參考文檔: j2se1_42_jni.chm JDK1.42的jni規(guī)范
JAVA程序
Java本地接接口(JNI)
(1)安裝JAVA
進行環(huán)境變量設置
新建變量path
變量值%path%;c:\JDK\bin
新建變量classpath
變量值.;c:\JDK\tools.jar?(”.”和”
c:\JDK\tools.jar”)
簡單例子
public class Example
{
public static void main(String args[])
{
System.out.println("hello
java!");
}
}
正常運行
開始編寫HelloWorld程序,由于涉及到要編寫c/c++代碼因此我們會在開發(fā)中使用Microsoft?VC++工具。編寫java代碼,我們在硬盤上建立一個hello目錄作為我們的工作目錄,首先我們需要編寫java代碼,在java代碼中聲明native方法
class?HelloWorld?{?public?native?void?displayHelloWorld();?//一個外部實現(xiàn)的方法
static?{?System.loadLibrary("hello");?//聲明所調(diào)用的庫名稱hello.dll
}?public?static?void?main(String[]?args)?{?new?HelloWorld().displayHelloWorld();?}?}?關鍵字native,表明這個方法使用java以外的語言實現(xiàn)。方法不包括實現(xiàn),因為我們要用c/c++語言實現(xiàn)它。System.loadLibrary("hello"),它是在靜態(tài)初始化塊中定義的,系統(tǒng)用來裝載hello共享庫,這就是我們在后面生成的hello.dll(如果在其他的操作系統(tǒng)可能是其他的形式,比如hello.so)
編譯java代碼
生成HelloWorld.class
javac?HelloWorld.java?生成HelloWorld.class文件?創(chuàng)建.h文件?這一步中我們要使用javah命令生成.h文件
生成HelloWorld.h
這個文件要在后面的c/c++代碼中用到,我們運行?javah?HelloWorld。這樣我們可以看到在相同目錄下生成了一個HelloWorld.h文件,文件內(nèi)容如下?在此我們不對他進行太多的解釋。?#include??#ifndef?_Included_HelloWorld?#define?_Included_HelloWorld?#ifdef?__cplusplus?extern?"C"?{?#endif?JNIEXPORT?void?JNICALL?Java_HelloWorld_displayHelloWorld?(JNIEnv?*,?jobject);?#ifdef?__cplusplus?}?#endif?#endif?編寫本地實現(xiàn)代碼?在這部分我們要用C/C++語言實現(xiàn)java中定義的方法,我們在VC++中新建一個Project,然后創(chuàng)建一個Hello.cpp文件,內(nèi)容如下?#include??#include?"HelloWorld.h"?#include??JNIEXPORT?void?JNICALL?Java_HelloWorld_displayHelloWorld(JNIEnv?*env,?jobject?obj)?{?printf("Hello?world!\n");?return;?}
注意我們這里include了?jni.h和剛才得到的HelloWorld.h文件。因此你要在VC++里面設置好,jni.h在JAVA_HOME/include里面。編譯通過后再生成hello.dll文件。
安裝VC++6.0
新建一個工程!工程名稱為HelloWorld(將生成HelloWorld.dll文件)
選擇Win32 Dynamic-Link Library
創(chuàng)建一個空工程
在工具—>選項—>目錄
添加C:\JDK\INCLUDE和C:\JDK\INCLUDE\WIN32在這些目錄文件夾中包含JNI所需的頭文件
在工作區(qū)中添加文件到目錄下!如下圖
Hello.cpp放置在source Files(源文件)里面
HelloWorld.h?jni.h放置在Header
Files(頭文件) 里面
再編譯
組建生成dll文件!
運行java程序?把上面生成的hello.dll文件復制到我們的工
總結
以上是生活随笔為你收集整理的java 调用本地接口_JAVA通过本地接口调用C++的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中for循环的简化_Java中f
- 下一篇: s3c2440移植MQTT