JNI編程新手入門:Java和C++的超簡單交互

系統環境

Mac OS X Yosemite 10.10.5java

java version "1.8.0_51"c++

摘要

簡單介紹什麼是JNI(Java Native Interface)。經過一個 HelloWorld 小程序,實現經過 Java 調用 C++ 打印 「 Hello Wolrd 」 。編程

什麼是JNI

在編程領域, JNI (Java Native Interface,Java本地接口)是一種編程框架,使得 Java 虛擬機中的 Java 程序能夠調用本地應用/或庫,也能夠被其餘程序調用。 本地程序通常是用其它語言( C 、 C++ 或彙編語言等)編寫的, 而且被編譯爲基於本機硬件和操做系統的程序。小程序

定義摘自維基百科。簡而言之,經過JNI可使 Java 程序和 C++ 程序直接通訊交互,不須要經過
如 .exe 等可執行文件流的方式去實現的交互。bash

編程實例

光說概念其實可能也是看得雲裏霧裏,不如直接就用一個實例來更加直觀的瞭解JNI編程吧。如今咱們來寫一個簡單的 HelloWorld 小程序框架

首先建立一個 JniTest.java 文件 , 鍵入以下代碼保存便可函數

public class JniTest {

  //導入lib文件
  static
  {
        System.loadLibrary("jnitest");
  }

  public JniTest()
  {
    //init()  
  }
  // 調用 c++ 代碼的函數
  public native void printHelloWorld();

  public static void main(String[] args) {
        new JniTest().printHelloWorld();

    }
}

接着在終端控制檯,執行操作系統

javac JniTest.java

若成功執行就會生成相應的 JniTest.class 文件。接着執行命令行

javah JniTest

若成功執行就會生成 JniTest.h 文件。文件裏已經根據咱們的 java 代碼自動生成了相應的 c++ 代碼,代碼以下:code

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

#ifndef _Included_JniTest
#define _Included_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniTest
 * Method:    printHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JniTest_printHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

那一長串以 JNIEXPORT 開頭的函數就是咱們的函數接口。接着咱們再建立一個相應的 JniTest.cpp 文件 ,實現 .h 中的函數,記得要包含 .h 頭文件。

#include <jni.h>
#include "JniTest.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_JniTest_printHelloWorld
  (JNIEnv *, jobject)
{
    printf("HelloWorld\n");
}

到這裏咱們的主要代碼編寫就已經完成啦。但要讓它跑起來還須要一點其餘的操做。咱們首先要編譯.cpp文件,這裏能夠直接在命令行使用 g++ -c JniTest.cpp命令。可是此時這麼鍵入是會報錯的,它會提示:

JniTest.cpp:2:10: fatal error: 'jni.h' file not found
#include <jni.h>
         ^
1 error generated.

由於默認的頭文件的搜索路徑上是沒有 jni.h文件的。咱們先得找到 jni.h文件在哪裏。MacOS下,它的文件路徑在 /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include (根據JDK版本不一樣,須要修改中間jdk文件夾的名字,不過最開始的 /Library/Java/JavaVirtualMachines/ 通常是不會變的)除了 jni.h 以外,我麼還須要 jni_md.h 它就在上述的include文件下的 darwin文件下,咱們能夠先在.cpp文件的目錄下建立 include 文件夾,而後把上述的兩個文件拷進去。接着執行

g++ -c JniTest.cpp -I ./include

若成功就會生成JniTest.o的目標文件,接着再執行

g++ -dynamiclib -o libjnitest.jnilib JniTest.o

就會生成libjnitest.jnilib文件,注意! 生成的文件名命名必定要是 lib + "java中讀取的庫文件名(如jnitest)" + .jnilib 不然java載入庫文件將會失敗!而後咱們在終端鍵入

java JniTest

就會看到終端打印出HelloWorld了 ! 咱們的Hello World小程序就完成啦!

相關文章
相關標籤/搜索