歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

初探JNI技術,HelloWorld 圖文詳細教程

1、什麼是JNI?

一種讓Java調用其他語言的技術。

本博文將會介紹JNI 調用C++的技術。

有關於此教程的所有代碼下載

------------------------------------------分割線------------------------------------------

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2014年資料/10月/9日/Ubuntu仿Mac主題:SnowBird

下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm

------------------------------------------分割線------------------------------------------

2、JNI 之 HelloWorld in JAVA

HelloWorld.java:

package com.hello;

public class HelloWorld { 
    public native void hello(String name); 
 
    public HelloWorld(){ 
   
    }
    static { 
      System.loadLibrary( "HelloWorld" );   
    } 

注意下,如果我們用JNI編出的文件叫: HelloWorld.dll ,那麼System.loadLibrary("HelloWorld"),不用加“.dll”。

TestHelloWorld.java:

package com.hello;

public class TestHelloWorld { 
    public static void main(String[] args) { 
        HelloWorld helloWorld = new HelloWorld(); 
        helloWorld.hello("emaster");
    } 

編譯一下,生成兩個class文件。

至此,java方面的代碼就完事了。

3、JNI 之 HelloWorld in C++ 選擇IDE

在開始之前,我推薦大家用VC++6.0,而不是CodeBlocks來編寫C++方面的代碼!

理由如下:

這是CodeBlocks生成的DLL的導出函數:

_Z44Java_com_regMonitor_RegMonitor_jniRegMonitorP7JNIEnv_P8_jobject@8

這是VC生成的DLL的導出函數:

發現沒有?CB生成的DLL導出函數多了一些:_Z44啊,P7JNIEnv_P8_jobject之類的。

導出函數多一些東西之後,會導致我們在Java中找不到對應的函數。

哎,也可能是我 CB沒有調整好編譯命令吧。總之我在VC下成功了。

Ps:

DLL查看導出函數器下載見本文上面的Linux公社資源下載

4、javah生成C++用的頭文件

我的工作目錄如下:

 D:\pub\workspace\JNIHelloWorld\src\com\hello 的目錄

2014-05-14  18:04    <DIR>          .
2014-05-14  18:04    <DIR>          ..
2014-05-14  18:04              218 HelloWorld.java
2014-05-14  18:04              207 TestHelloWorld.java

在com.hello下有上面提到的兩個java文件。(請注意,之前已經編譯過java文件,所以bin文件夾下有類文件!)

請注意我生成頭文件的目錄和命令

D:\pub\workspace\JNIHelloWorld\bin>javah com.hello.HelloWorld

D:\pub\workspace\JNIHelloWorld\bin>dir
2014-05-14  18:21    <DIR>          .
2014-05-14  18:21    <DIR>          ..
2014-05-14  18:04    <DIR>          com
2014-05-14  18:21              475 com_hello_HelloWorld.h

看到沒有,生成了一個頭文件:com_hello_HelloWorld.h。

如果目錄不對,很可能報錯如下:

錯誤:無法訪問 HelloWorld
錯誤的類文件: D:\pub\workspace\JNIHelloWorld\bin\com\hello\HelloWorld.class
類文件包含錯誤的類: com.hello.HelloWorld
請刪除該文件或確保該文件位於正確的類路徑子目錄中。
com.sun.tools.javac.util.Abort
        at com.sun.tools.javac.comp.Check.completionError(Check.java:162)
        at com.sun.tools.javadoc.DocEnv.loadClass(DocEnv.java:147)
        at com.sun.tools.javadoc.RootDocImpl.<init>(RootDocImpl.java:77)
        at com.sun.tools.javadoc.JavadocTool.getRootDocImpl(JavadocTool.java:159
)
        at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:330)
        at com.sun.tools.javadoc.Start.begin(Start.java:128)
        at com.sun.tools.javadoc.Main.execute(Main.java:66)
        at com.sun.tools.javah.Main.main(Main.java:147)
javadoc: 錯誤 - 致命錯誤
2 錯誤

5、JNI 之 HelloWorld in C++ 詳細步驟

5.1、步驟1

VC新建項目,選擇Win32 Dynamic-Link Library項目(生成DLL的),默認即可。

我的項目名字為:JNIHelloWorld。

5.2、步驟2

把第4步的頭文件:com_hello_HelloWorld.h 放到VC中。

5.3、步驟3

修改下輸出DLL的名字:VC菜單 -> 工程 -> 設置 -> 連接 ->  輸出文件名 這一欄,改成:Debug/HelloWorld.dll

這樣子就和Java代碼中的dll名字一樣了,其實可以手動F2修改的,這裡設置後就不能每次都去修改了,懶人。

5.4、步驟4

把HelloWorld.dll放到Java項目的根目錄下,我這裡是根目錄是:

D:\pub\workspace\JNIHelloWorld

所以該dll的路徑是:

5.5、步驟5

配置jni頭文件,不然C++會報錯找不到該頭文件:

就是到jdk的安裝目錄下include下把以下相應的文件,復制到vc目錄下的include文件夾下:

\jdk\include\jni.h
\jdk\include\win32\jawt_md.h
\jdk\include\win32\jni_md.h

上面主是jdk安裝目錄下的三個文件,分別復制它們到vc目錄下的include文件夾下。如我的安裝位置是:

D:\Program Files\Microsoft Visual Studio\VC98\Include

你們可以根據自己的安裝位置自行確定。

5.6、步驟6 

代碼如下:

com_hello_HelloWorld.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_hello_HelloWorld */

#ifndef _Included_com_hello_HelloWorld
#define _Included_com_hello_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:    com_hello_HelloWorld
 * Method:    hello
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_hello_HelloWorld_hello
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

JNIHelloWorld.cpp:

// JNIHelloWorld.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "com_hello_HelloWorld.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved
      )
{
    return TRUE;
}


JNIEXPORT void JNICALL Java_com_hello_HelloWorld_hello
 (JNIEnv *, jobject, jstring)

{
 printf("I am in C++!\n");
 return;
}

6、效果如下: 

可以看到,我們在Java中,調用C++的方法成功!

至此,一個完整的HelloWorld版本的JNI過程,就完成了。

Tiny6410內核模塊編譯之HelloWorld  http://www.linuxidc.com/Linux/2013-12/93634.htm

HelloWorld之Hibernate版 http://www.linuxidc.com/Linux/2014-04/99294.htm

在Ubuntu上編寫Qt HelloWorld程序 http://www.linuxidc.com/Linux/2014-06/103671.htm

Tiny6410內核模塊編譯之HelloWorld http://www.linuxidc.com/Linux/2013-12/93634.htm

用Pthreads進行共享內存編程----HelloWorld http://www.linuxidc.com/Linux/2013-04/83103.htm

Hadoop實例之HelloWorld http://www.linuxidc.com/Linux/2012-12/75406.htm

Qt Creator for PlayBook上的HelloWorld (Windows版) http://www.linuxidc.com/Linux/2012-05/60653.htm

Tiny6410 簡單的交叉編譯helloworld      http://www.linuxidc.com/Linux/2012-03/56732.htm

Copyright © Linux教程網 All Rights Reserved