cygwin+ndk+eclipse下JNI技術入門

一、JNI的編寫步驟
1)編寫帶有native 聲明的java類.
2)編譯java文件成class類
3)使用javah -jni com.ikags.project.XXXX 編譯成.h文件
4)使用C/C++編寫代碼
5)編寫makefile文件,將.h和.c(.cpp)文件編譯成.dll(.so)文件
6)將.dll(.so)文件提供給項目,用system.loadLibrary方法調用.java

 

二、編寫makefile文件
make執行時,自動尋找Makefile(makefile)文件,而後執行編譯工做。
在一個Makefile中一般包含下面內容:
1)須要由make工具建立的目標體(target),一般是目標文件或可執行文件。
2)要建立的目標體所依賴的文件(dependency_file)。
3)建立每一個目標體時須要運行的命令(command)。eclipse

 

三、Android.mk寫法
(1)Android.mk文件首先須要指定LOCAL_PATH變量,用於查找源文件。因爲通常狀況下
Android.mk和須要編譯的源文件在同一目錄下,因此定義成以下形式:
LOCAL_PATH:=$(call my-dir)
上面的語句的意思是將LOCAL_PATH變量定義成本文件所在目錄路徑。
(2)Android.mk中能夠定義多個編譯模塊,每一個編譯模塊都是以include $(CLEAR_VARS)開始
以include $(BUILD_XXX)結束。
include $(CLEAR_VARS)
CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE爲你清除除LOCAL_PATH之外的全部LOCAL_XXX變量,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示編譯成靜態庫
include $(BUILD_SHARED_LIBRARY)表示編譯成動態庫。
include $(BUILD_EXECUTABLE)表示編譯成可執行程序工具

 

四、jni調用例子
編碼前提,cygwin+ndk+eclipse搭建的開發環境,可以正常編譯運行
第一個jni測試程序仍是打印hello,world
4.1寫好java,native方法,以及調用lib名
package jni;
public class Hello
{
    public native void sayHello();
    static
    {
     System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary("hello");
    }
    public static void main(String[] args)
    {
     
        Hello h = new Hello();
        h.sayHello();
    }
}
4.二、使用javah -jni 全包名+類名 編譯成.h文件
編譯經過後,class文件在工程的bin目錄下。
進入到dos狀態,cd 到工程的bin目錄,運行命令以下:
 javah -jni jni.Hello
正常狀況下,jni_Hello.h會出如今bin目錄下測試

4.三、生成.so文件
1)新建hello.c文件
而後咱們創建一個C++工程,在src目錄下創建一個jni目錄,
將剛剛創建好的jni_Hello.h文件copy到jni目錄,
並在jni目錄下創建一個 hello.c文件,用來實現頭文件中聲明的方法,代碼以下:
#include <jni.h>
#include "jni_Hello.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endifui


JNIEXPORT void JNICALL Java_jni_Hello_sayHello(JNIEnv *env, jobject obj) {
   printf("Hello World !\n");
   return;
}編碼

2)新建Android.mk文件
在jni目錄下(即hello-jni.c 同級目錄下)新建一個Android.mk文件
LOCAL_PATH := $(call my-dir)
include  $(CLEAR_VARS)
LOCAL_MODULE    := hello
#LOCAL_MODULE,編譯的目標對象,以標識你在Android.mk文件中描述的每一個模塊
LOCAL_SRC_FILES := hello.c
#LOCAL_SRC_FILES變量必須包含將要編譯打包進模塊中的C或C++源代碼文件
include  $(BUILD_SHARED_LIBRARY)
#BUILD_SHARED_LIBRARY表示編譯生成共享庫spa

運行cygwin, 到C++工程目錄下,以下:
cd cygdrive/c/workspace/hello/src/jni
運行$NDK/ndk-build,以下:
$ ndk-build
Cygwin         : Generating dependency file converter script
Compile thumb  : hello <= hello.c
SharedLibrary  : libhello.so
Install        : libhello.so => libs/armeabi/libhello.so
若是提示信息如上所示,表示.so共享庫文件成功生成對象

so文件拷貝到java的加載庫LD_LIBRARY_PATH指向的路徑中。blog

5,運行java工程ip

 

出處:htpp://blog.sina.com.cn/staratsky

相關文章
相關標籤/搜索