Java 中嵌入c/c++

jack_gogo 12年前發布 | 62K 次閱讀 C/C++開發 java, c++, c

    Java Native Interface(JNI)Java語言的本地編程接口,是J2SDK的一部分。在java程序中,我們可以通過JNI實現一些用java語言不便實現的功能。通常有以下幾種情況我們需要使用JNI來實現。  

      標準的java類庫沒有提供你的應用程序所需要的功能,通常這些功能是平臺相關的

  如果你希望使用一些已經有的類庫或者應用程序,而他們并非用java語言編寫的

   程序的某些部分對速度要求比較苛刻,你選擇用匯編或者c語言來實現并在java語言中調用他們

1.編寫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

2
。編譯java代碼

javac HelloWorld.java
生成HelloWorld.class文件

3
。創建.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
4
編寫本地實現代碼

在這部分我們要用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.hJAVA_HOME/include里面。編譯通過后再生成hello.dll文件。

5
運行java程序

把上面生成的hello.dll文件復制到我們的工作目錄,這時候我們的目錄中包括HelloWorld.javaHelloWorld.classhello.dll文件。運行java HelloWorld命令,則可在控制臺看到
Hello world|
的輸出了。

Linux下測試jni
1
、在測試用戶下建立srclib目錄

2
、進入src目錄編寫HelloWorld.java
class HelloWorld {
/* Native method declaration */
public native void displayHelloWorld();
/* Use static intializer */
static {
System.loadLibrary("hello");
}
/* Main function calls native method*/
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
3
、然后
javac HelloWorld.java
4
、使用 javah 工具生成 HelloWorld.h 文件

javah HelloWorld
5
、編寫HelloWorld.c
#include <jni.h>;
#include "HelloWorld.h"
#include <stdio.h>;

JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
6
、編譯c的動態庫

gcc -shared -o $HOME/lib/libhello.so HelloWorld.c
注意$HOME/lib目錄要加入到環境變量LD_LIBRARY_PATH中去
7
java HelloWorld運行程序

jni 關于dll文件的生成以及找不到jni.h的解決辦法

首先是關于dll文件的生成: 方法如下: 打開VC++6.0,新建->; 工程 ->; win32 Dynamic-Link Library在向導中選擇空工程添加如用javah生成的頭文件和自己寫的一個cpp文件,然后編譯運行,如果沒有出現錯誤,既可以在編譯成功的 debug文件夾中找到dll文件,如果出現找不到jni.h的錯誤,那么用如下方法解決: fatal error C1083: Cannot open include file: 'jni.h': No such file or directory 將以下文件: \jdk\include\jni.h \jdk\include\win32\jawt_md.h \jdk\include\win32\jni_md.h 復制到Visual Studio.net的安裝目錄下的\Vc7\include目錄中如果是VC6.0,自己找相應的目錄即可!

 本文由用戶 jack_gogo 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!