国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

hello-jni實例講解

2019-11-09 15:04:21
字體:
來源:轉載
供稿:網友

一、Jni簡介

Jni全稱是java Native Interface(Java本地接口),它是java平臺的一部分,允許Java代碼和其他語言編寫的代碼進行交互,它使得在Java虛擬機(JVM)內部運行的Java代碼可以和其他語言編寫的應用程序或庫進行交互操作。

二、hello-jni項目簡介

截圖如下:

這里先對各個文件夾進行分析:

1、jni文件夾

要想在Java項目里或是Android項目里面調用native代碼必須在項目下面新建一個jni目錄,在這個目錄里面編寫有關native代碼,并且編寫編譯規則(Android.mk文件),這里重點細說一下這個文件~

這個文件主要是規定編譯器如何去生成.so文件、引用的頭文件目錄、需要編譯的.c .cpp .a等文件,hello-jni里面的Android.mk文件很簡單并且只有一個,所以先簡單分析一下hello-jni提供的Android.mk文件~

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello-jniLOCAL_SRC_FILES := hello-jni.cinclude $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)

LOCAL_PATH這個變量用于給定當前文件的路徑,my-dir這個宏是由Build System提供的,用于指出當前文件夾所在的路徑。

include $(CLEAR_VARS)

這個include的作用就是指向一個編譯腳本,指向哪個腳本由括號內的變量決定,CLEAR_VARS指向了一個清理以LOCAL_開頭的變量(LOCAL_PATH這個變量排除在外,因為每個模塊都會用到當前文件的路徑)。在Android.mk中可能會存在很多的模塊,每個模塊都會有一些變量,而且這些變量又都是全局的,Build System每次只能編譯一個模塊,所以在每一個模塊的最開始都要執行CLEAR_VARS這個腳本來清理其他模塊的變量。

LOCAL_MODULE :=hello-jni

這個變量是規定Android.mk文件執行完成之后生成的so文件的名字,在生成so文件的過程中Build System會自動加上lib和.so后綴,比如這個,最后會生成libhello-jni.so這個文件,這個文件可以再代碼里面加載,代碼如下:

    /* this is used to load the 'hello-jni' library on application     * startup. The library has already been unpacked into     * /data/data/com.example.hellojni/lib/libhello-jni.so at     * installation time by the package manager.     */    static {        System.loadLibrary("hello-jni");    }

LOCAL_SRC_FILES :=hello-jni.c

這個變量規定要打包的Native的源碼,如示例中的hello-jni.c,這里不需要列出頭文件,因為Build System會自動加載頭文件的,缺省的C++擴展名為cpp,要想改變C++的擴展名,修改LOCAL_CPP_EXTENSION就可以了。

include $(BUILD_SHARED_LIBRARY)

這個BUILD_SHARED_LIBRARY是由Build System提供的一個變量,指向一個編譯腳本,用來收集上一次執行CLEAR_VARS這個腳本之后所有的LOCAL信息,并且決定編譯生成什么類型的文件。

BUILD_SHARED_LIBRARY 編譯為動態庫

BUILD_STATIC_LIBRARY 編譯為靜態庫

BUILD_EXECUTABLE 編譯為Native程序

這個hello-jni的Android.mk文件就說完了~

Application.mk:這個文件是描述你的應用程序中所需要的模塊(靜態庫還是動態庫)

APP_ABI :=all 這個表示編譯出所有平臺。

我們知道,這個ABI表示ApplicationBinaryInterface(應用程序二進制接口),一個應用程序一般是由高級語言編寫完成之后,經過編譯生成匯編程序,然后在鏈接生成二進制文件,這個生成二進制文件的過程中有一個ABI的概念,決定了生成的二進制程序可以運行在哪個CPU架構上(也就是不同的平臺)

這個Application.mk文件就說完了~

hello-jni.c文件是Native源碼文件

/* * Copyright (C) 2009 The Android Open Source PRoject * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */#include <string.h>#include <jni.h>/* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java */jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){#if defined(__arm__)  #if defined(__ARM_ARCH_7A__)    #if defined(__ARM_NEON__)      #if defined(__ARM_PCS_VFP)        #define ABI "armeabi-v7a/NEON (hard-float)"      #else        #define ABI "armeabi-v7a/NEON"      #endif    #else      #if defined(__ARM_PCS_VFP)        #define ABI "armeabi-v7a (hard-float)"      #else        #define ABI "armeabi-v7a"      #endif    #endif  #else   #define ABI "armeabi"  #endif#elif defined(__i386__)   #define ABI "x86"#elif defined(__x86_64__)   #define ABI "x86_64"#elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */   #define ABI "mips64"#elif defined(__mips__)   #define ABI "mips"#elif defined(__aarch64__)   #define ABI "arm64-v8a"#else   #define ABI "unknown"#endif    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");}這個源文件的編寫和普通的C文件不太一樣,因為是和Java打交道的嘛~

這個jstring是jvm里面的字符串,下面是Java和C++的類型在JVM里面的映射:

函數名稱之所以要這么寫是因為要和調用這個函數的java代碼交互,截圖如下:

Java是固定的,com_example_hellojni這個是包名,HelloJni這個是類名,stringFromJNI這個就是Java的native方法了~

這個說完了函數名稱編寫,然后看一下這個函數的參數

第一個JNIEnv類型的參數,通過這個參數我們可以在Native代碼里面獲取一些Java代碼的信息。我們在Java端的函數是沒有這個參數的,這個參數是從Java端自動傳過來的,作用是提供給JNI一個Java的運行環境,在Java里面就是JVM,在Android里面就是Dalvik VM。

第二個jobject類型的參數的意思是,如果這個Native方法是靜態的話,jobject表示的就是這個包含這個Native方法的類的實例,如果這個Native方法不是靜態的話,jobject表示的就是這個類的對象的實例。

hello-jni.c就到這里了。

有什么疑問可以加我QQ:763949771,一起交流學習。如有錯誤請留言指正~


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤峰县| 扶余县| 丹东市| 唐海县| 阳原县| 宁蒗| 雷波县| 浑源县| 德昌县| 拜城县| 丁青县| 宁陕县| 彭水| 永寿县| 广南县| 夹江县| 天门市| 香河县| 剑河县| 焦作市| 哈密市| 兴化市| 桑日县| 库伦旗| 乡城县| 鄂州市| 定日县| 福泉市| 冷水江市| 武强县| 江华| 渭南市| 宣恩县| 临沧市| 舟山市| 平凉市| 如东县| 邵武市| 泾阳县| 神木县| 聂荣县|