Windows 下JNI開發流程(visual studio + eclipse)

    轉載請註明出處:

 

       JNI全稱是Java Native Interface(Java本地接口)單詞首字母的縮寫,本地接口就是指用C和C++開發的接口。由於JNI是JVM規範中的一部份,因此可以將我們寫的JNI程序在任何實現了JNI規範的Java虛擬機中運行。同時,這個特性使我們可以複用以前用C/C++寫的大量代碼。

 

       開發JNI程序會受到系統環境的限制,因爲用C/C++語言寫出來的代碼或模塊,編譯過程當中要依賴當前操作系統環境所提供的一些庫函數,並和本地庫鏈接在一起。而且編譯後生成的二進制代碼只能在本地操作系統環境下運行,因爲不同的操作系統環境,有自己的本地庫和CPU指令集,而且各個平臺對標準C/C++的規範和標準庫函數實現方式也有所區別。這就造成使用了JNI接口的JAVA程序,不再像以前那樣自由的跨平臺。如果要實現跨平臺,就必須將本地代碼在不同的操作系統平臺下編譯出相應的動態庫。

 

JNI開發流程主要分爲以下4步:

1、在eclipse中編寫聲明瞭native方法的Java類

2、生成JNI頭文件

3、在visual studio 中創建DLL 項目,實現 JNI頭文件中的方法

4、在eclipse中設置Native library location,路徑爲 visual studio 中生成的DLL 文件路徑,運行java 程序

 

 

通過上面的介紹,相信大家對JNI及開發流程有了一個整體的認識,下面通過一個HelloWorld的示例,再深入瞭解JNI開發的各個環節及注意事項。

第一步、在eclipse中新建一個HelloWorld.java

package com.study.jnilearn;  
  
public class HelloWorld {  
      
    public static native String sayHello(String name);  // 1.聲明這是一個native函數,由本地代碼實現  
  
    public static void main(String[] args) {  
        String text = sayHello("yangxin");  // 3.調用本地函數  
        System.out.println(text);  
    }  
      
    static {  
        System.loadLibrary("HelloWorld");   // 2.加載實現了native函數的動態庫,只需要寫動態庫的名字  
    }  
  
}  

 

第二步、生成JNI頭文件

1.配置 javah External tools
   
 

如圖點擊第二項 External tools Configurations


2.配置  如圖 


 



${project_loc}/src 
-classpath ${project_loc}/bin/classes -d ${project_loc}/jni -jni ${java_type_name} 

 

3. 執行jExternal tools( javah)生成JNI 頭文件

第三步、用本地代碼實現.h頭文件中的函數

將第二步中生成的頭文件copy 過來

 

com_study_jnilearn_HelloWorld.h:

/* DO NOT EDIT THIS FILE - it is machine generated */  
#include <jni.h>  
/* Header for class com_study_jnilearn_HelloWorld */  
  
#ifndef _Included_com_study_jnilearn_HelloWorld  
#define _Included_com_study_jnilearn_HelloWorld  
#ifdef __cplusplus  
extern "C" {  
#endif  
/* 
 * Class:     com_study_jnilearn_HelloWorld 
 * Method:    sayHello 
 * Signature: (Ljava/lang/String;)Ljava/lang/String; 
 */  
JNIEXPORT jstring JNICALL Java_com_study_jnilearn_HelloWorld_sayHello  
  (JNIEnv *, jclass, jstring);  
  
#ifdef __cplusplus  
}  
#endif  
#endif  

 

HelloWorld.c:

// HelloWorld.c  
  
#include "com_study_jnilearn_HelloWorld.h"  
  
#ifdef __cplusplus  
extern "C"  
{  
#endif  
  
/* 
 * Class:     com_study_jnilearn_HelloWorld 
 * Method:    sayHello 
 * Signature: (Ljava/lang/String;)Ljava/lang/String; 
 */  
JNIEXPORT jstring JNICALL Java_com_study_jnilearn_HelloWorld_sayHello(  
        JNIEnv *env, jclass cls, jstring j_str)  
{  
    const char *c_str = NULL;  
    char buff[128] = { 0 };  
    c_str = (*env)->GetStringUTFChars(env, j_str, NULL);  
    if (c_str == NULL)  
    {  
        printf("out of memory.\n");  
        return NULL;  
    }  
    (*env)->ReleaseStringUTFChars(env, j_str, c_str);  
    printf("Java Str:%s\n", c_str);  
    sprintf(buff, "hello %s", c_str);  
    return (*env)->NewStringUTF(env, buff);  
}  
  
#ifdef __cplusplus  
}  
#endif  

第六步、運行Java程序

       Java在調用native(本地)方法之前,需要先加載動態庫。如果在未加載動態之前就調用native方法,會拋出找不到動態鏈接庫文件的異常。如下所示:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.study.jnilearn.HelloWorld.sayHello(Ljava/lang/String;)Ljava/lang/String;  
    at com.study.jnilearn.HelloWorld.sayHello(Native Method)  
    at com.study.jnilearn.HelloWorld.main(HelloWorld.java:9)  

設置Native library location

通過ALT + ENTER 調出properties 選項卡

 

費了那麼大勁,終於可以運行寫好的Java程序了,結果如下:

Java Str:yangxin  
hello yangxin  

 

注意事項:

    java 程序的版本和 dll 程序的版本要對上,例如x64的Java程序 需要編寫 x64的dll 動態庫

參考: http://blog.csdn.net/xyang81/article/details/41777471

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章