zoukankan      html  css  js  c++  java
  • NDK jni mk文件 so文件 巴啦啦 初体验

    概念
    JNI(Java Native Interface,Java本地接口),实现了Java和其他语言的交互(主要是C/C++),如:Java程序通过JNI调用C/C++编写的在Windows上运行的DLL动态链接库。

    so(shared object,共享对象),Linux系统中的动态库,类似于Windows系统中的DLL。.so有时被直接调用,有时会参与到编译中。Android由Linux内核发展而来,因此在Android系统中也使用.so。

    Android NDK(Android Native Development Kit),是Google提供的一系列的工具,简化通过JNI将C/C++动态库编译为.so库的过程。NDK集成了交叉编译器,并提供了相应的.mk文件隔离CPU、平台、ABI等差异,开发者只需要简单修改mk文件,执行编译脚本就可以创建.so。

    NDK与JNI的关系:

    JNI是Java与其他语言交互的机制,是Java语言自身的特性,与Android无关。

    Android在框架上分为Application应用层、Application Framework应用框架层、libraries类库、Linux kernel内核。在应用框架层以及之上,使用Java语言进行开发;在此之下,Android自身的类库、驱动使用C/C++编写,再通过JNI提供接口给上层的Java调用。所以,Android框架使用了大量的JNI技术,让应用层的开发人员使用Java操控C/C++。

    通常的Android开发都在应用框架层以及之上进行,但有时也需要对底层进行实现。显然,对底层的开发要复杂得多,NDK则是Google推出的帮助开发者通过C/C++编写应用的开发包,包含部分Android底层中常用的C/C++的头文件、库文件、说明文档和示例代码。

    NDK只需要简单地编写几个.mk文件即可将c/c++代码编译为Android的java工程/Android手机可以识别、加载和运行的库或者应用程序。

    Android.mk
    ndk-build命令实际是执行了%NDK_PROJECT_PATH%/jni/Android.mk这个makefile文件,如果未配置%NDK_PROJECT_PATH%环境变量,则需要定位到工程目录。同时,待编译的.c和编译配置文件Android.mk也需要位于名为jni的目录下。

    Android.mk是NDK编译的配置文件,其中定义了需要编译的.c文件、依赖的.h头文件、编译出的so库名等等信息,是使用NDK进行编译的关键。

    为什么使用NDK

    • 代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

    • 可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。

    • 提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。

    • 便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。

    mk文件中的语法:

    1.LOCAL_PATH

    这个变量用于给出当前文件的路径。你必须在Android.mk的开头定义。例如:

    LOCAL_PATH := $(call my-dir)

    2.LOCAL_MODULE

    这是你模块的名字,它必须是唯一的,而且不能包含空格。你必须在包含任一的$(BUILD_XXXX)脚本之前定义它。模块的名字决定了生成文件的名字。

    3.LOCAL_MODULE_FILENAME

    默认的情况下,编译生成的文件名为lib$(LOCAL_MODULE).so/a在使用的此变量后,会用此变量的名来覆盖系统默认的生成文件名。例如:

    LOCAL_MODULE := foo-version-1

    LOCAL_MODULE_FILENAME := foo生成的文件名为libfoo.so/a

    4.LOCAL_SRC_FILES

    要直接传递给编译器的源代码文件列表。只要列出要传递给编译器的文件即可,因为编译系统自动为你计算依赖

    5.LOCAL_C_INCLUDES


    可选的路径列表,相对于NDK的根目录,当编译所有的源文件(C、C++、或者汇编)时将被追加到搜索路径中
    例如:
    LOCAL_C_INCLUDES:=sources/foo
    或者
    LOCAL_C_INCLUDES:=$(LOCAL_PATH)/../foo

    6.LOCAL_EXPORT_CFLAGS

    定义这个变量用来记录C/C++编译器标志集合

         include $(CLEAR_VARS)

            LOCAL_MODULE := foo

            LOCAL_SRC_FILES := foo/foo.c

            LOCAL_EXPORT_CFLAGS := -DFOO=1

            include $(BUILD_STATIC_LIBRARY)

      定义-DFOO 为1

    7.import-module

    此函数用于按模块名称来查找和包含模块的 Android.mk 文件。 典型的示例如下所示:

    $(call import-module,<name>) 

    在此示例中,构建系统在 NDK_MODULE_PATH 环境变量所引用的目录列表中查找以 <name> 标记的模块,并且自动包括其 Android.mk 文件。

    8.include

    include可Android多以这样的形式出现,如:include $( CLEAR_VARS),include $(BUILD_SHARED_LIBRARY).其实这个include可以理解成"执行"的意思,那么执行什么呢?当然是看后边的宏了.

    宏CLEAR_VARS表示清除一些变量.

    宏BUILD_SHARED_LIBRARY表示生成共享库,即生成.so文件,它负责收集自从上次调用 include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。

    因此include $(BUILD_SHARED_LIBRARY)就是指定在/system/lib/目录下生成一个lib$(LOCAL_MOUDULE).so文件,同样类型的宏如下:

    CLEAR_VARS                                             清除LOCAL_xxx变量
    BUILD_SHARED_LIBRARY                     在/system/lib/目录下生成lib$(LOCAL_MOUDULE).so文件
    BUILD_STATIC_LIBRARY                         生成lib$(LOCAL_MOUDULE).a文件
    BUILD_EXECUTABLE                               在/system/bin/目录下生成可执行文件
    BUILD_PACKAGE                                      编译成一个apk文件

  • 相关阅读:
    循环
    list和tuple
    Python字符串和编码注意点
    【转载】国内安卓推送的希望
    【转载】Android属性动画和视图动画的区别
    【转载】Android 属性动画详解
    【转载】 android 属性动画详解
    java8 新特性学习详细篇2
    java8 新特性详细篇
    JAVA8十大新特性
  • 原文地址:https://www.cnblogs.com/lixiao24/p/10686403.html
Copyright © 2011-2022 走看看