Android架構分析之JNI

來源:互聯網
上載者:User

Android版本:2.3.7_r1

Linux核心版本:android-goldfish-2.6.29

 

在我們開始分析Android硬體抽象層HAL之前,我們先來通過一個簡單的例子看一下JAVA是怎樣通過Java Native Interface(JNI)與C/C++代碼進行互動的。

首先我們來編寫NativeTest.java,其代碼如下:

[cpp]   1public class NativeTest { 
 2    public native static double max(double a, double b); 
 3 
 4    static { 
 5        System.loadLibrary("max"); 
 6    } 
 7 
 8    public static void main(String[] args) { 
 9        System.out.println(max(1, 2)); 
10    } 
11} 

 1public class NativeTest {
 2    public native static double max(double a, double b);
 3
 4    static {
 5        System.loadLibrary("max");
 6    }
 7
 8    public static void main(String[] args) {
 9        System.out.println(max(1, 2));
10    }
11}第2行,聲明max函數是一個native函數,後面由C語言實現。

第5行,匯入系統庫max,在Linux下,其名稱為libmax.so。

第9行,調用max函數,該函數的實現在max庫中。

接下來,我們要做的是編譯JAVA源碼,並且使用javah工具產生一個C標頭檔。

# javac NativeTest.java

# javah -jni NativeTest

以上兩個命令執行完後,目前的目錄下會產生NativeTest.class和NativeTest.h兩個檔案。

開啟NativeTest.h,其內容如下:

[cpp]   1/* DO NOT EDIT THIS FILE - it is machine generated */ 
 2#include <jni.h> 
 3/* Header for class NativeTest */ 
 4 
 5#ifndef _Included_NativeTest 
 6#define _Included_NativeTest 
 7#ifdef __cplusplus 
 8extern "C" { 
 9#endif 
10/*
11 * Class:     NativeTest
12 * Method:    max
13 * Signature: (DD)D
14 */ 
15JNIEXPORT jdouble JNICALL Java_NativeTest_max 
16  (JNIEnv *, jclass, jdouble, jdouble); 
17 
18#ifdef __cplusplus 
19} 
20#endif 
21#endif 

 1/* DO NOT EDIT THIS FILE - it is machine generated */
 2#include <jni.h>
 3/* Header for class NativeTest */
 4
 5#ifndef _Included_NativeTest
 6#define _Included_NativeTest
 7#ifdef __cplusplus
 8extern "C" {
 9#endif
10/*
11 * Class:     NativeTest
12 * Method:    max
13 * Signature: (DD)D
14 */
15JNIEXPORT jdouble JNICALL Java_NativeTest_max
16  (JNIEnv *, jclass, jdouble, jdouble);
17
18#ifdef __cplusplus
19}
20#endif
21#endif第15-16行,可以看到,該標頭檔中聲明了一個函數Java_NativeTest_max,這就是需要我們在C程式中實現的函數,它對應JAVA代碼中調用的max函數。

編寫C程式max.c,實現Java_NativeTest_max函數,其代碼如下:

[cpp]  1#include "NativeTest.h" 
2JNIEXPORT jdouble JNICALL Java_NativeTest_max 
3(JNIEnv * jni_env, jclass class, jdouble a, jdouble b) 
4{ 
5    return a > b? a: b; 
6} 

1#include "NativeTest.h"
2JNIEXPORT jdouble JNICALL Java_NativeTest_max
3(JNIEnv * jni_env, jclass class, jdouble a, jdouble b)
4{
5    return a > b? a: b;
6}Java_NativeTest_max函數的作用是返回兩個參數較大的那個。

下面我們需要編譯產生動態連結程式庫libmax.so,在編譯之前,先配置環境變數:

# export C_INCLUDE_PATH=$C_INCLUDE_PATH:$JAVA_HOME/include

# export C_INCLUDE_PATH=$C_INCLUDE_PATH:$JAVA_HOME/include/linux

# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

編譯動態連結程式庫:

# gcc max.c -fPIC -shared -o libmax.so

在目前的目錄下會產生動態連結程式庫檔案libmax.so,執行JAVA程式:

# java NativeTest

2.0

上面的過程就是使用JNI串連JAVA代碼與C代碼的過程。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.