jni简介及openSSL静态动态编译

来源:互联网 发布:php抓取百度搜索结果 编辑:程序博客网 时间:2024/05/16 12:25

jni简介及openSSL静态动态编译

jni的定义

即java native interface,提供了若干api实现了java和其他语言的通信(c & c++)。

jni的优点及缺点

优点

  • 可以使用标准java api不能提供的功能,比如DICOM(医学数字成像和通信)。
  • 保护核心代码,c/c++的库反汇的难度较大,可以将加密key,或者重要的字符串信息之类的。
  • 便于移植,用c/c++写的库文件可以方便的在嵌入式平台上再次使用。类似与cocos2d-x,只需要编写一次代码,经过不同开发平台编译之后可以在android,ios,pc上面运行。

缺点

  • 一旦使用jni,程序不再垮平台,需要在不同的系统环境下重新编译(arm,arm64,x86,mips等不同cpu架构都需要重新编译)
  • 程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,应该让本地方法集中在少数几个类中。这样就降低了java和c之间的耦合性。

ndk

native development kit,是一系列工具的集合,帮助开发者快速开发C(c++)的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件,就可以创建出so。

C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)

cpu7种架构:armeabi,armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64

android不同版本相关:5.0中ndk支持64位6.0中需要静态编译openssl库(正在讲OpenSSL替换为BoringSSL)7.0中直接不允许调用非公有的api

ndk环境配置及openssl静态编译及动态编译介绍

下载ndk(android-ndk-r10),并配置ndk的环境变量。

windows环境下配置ndk变量与配置java和android环境变量相同。动态编译直接通过cmd命令行执行ndk-build来运行。静态编译通过windows编译的话经常报一些包找不到等错误。

下载cygwin(模拟Linux环境,其实开发ndk只需要上面的ndk环境即可正常开发,需要cygwin的原因是ndk在windows环境上面经常出问题,交叉编译各种bug)。

配置cygwin的注意事项:  1.安装的时候记得勾选shell 和devel  2.配置环境变量:    2.1 配置cygwin中的ndk环境变量(不用配置也行):       在etc目录下的profile下配置如下:      PATH="/usr/local/bin:/usr/bin:${PATH}/cygdrive/d/android-ndk-r11c:${PATH}"    2.2 配置ndk-build的指令:      在home中的user(根据电脑用户名不一样而改变)下的.bash_profile中配置如下:      export NDK_BUILD=/cygdrive/d/android-ndk-r10/ndk-build(要注意等号左右不能带空格)

openssl的动态编译库的编译(需要so):

编译所需要的so文件:

第一种方法(自己编译):

  • 下载github上面的官方的开源项目openssl
  • 配置android脚本,脚本地址
  • 具体配置方法
  • openssl官方英文说明

    注意:cygwin用此种方法编译的话,则需要在安装的时候配置wget,make(Devel目录下)等一系列命令。
    如果不想重新安装cygwin则可以利用apt-cyg命令(http://blog.csdn.net/forlong401/article/details/8517711).

第二种方法:

直接下载包含5个平台的动态库,不包含.a文件

动态编译的步骤(eclipse):

  • 在eclipse上面建立一个新的项目。或者在原有项目中也可。
  • 将自己写的.c和.h以及android.mk,Application.mk放入jni目录中
  • 得到so文件之后,将其放入ndk中对应的android版本平台里面(eg: android-ndk-r10/platforms/android-19)中,并根据不同平台将libcrypto和libssl的so分别放入到对应的lib中。
  • 将openssl的头文件放入项目中,具体的放置的路径可以配置(openssl项目中有include目录下)
  • 配置android.mk,Application.mk文件
  • cd 到工程目录
  • 执行ndk-build命令(如果在cygwin中执行配置了命令,则根据自己配置的命令执行,如$NDK_BUILD)
  • 得到动态编译的so文件。

    注意事项:
    写的.c文件中的包名要跟自己调用的方法的包名一样。

eg: 假设我要编译一个用openssl的so,so的名称为zty
则android.mk配置可以写成:

#即jni目录下面一层的路径LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := zty#openssl的头文件放置的目录LOCAL_C_INCLUDES := $(LOCAL_PATH)/../openssl/include#log包LOCAL_LDLIBS += -lcrypto -lssl -llogLOCAL_SRC_FILES += encryptkey.c base64.cinclude $(BUILD_SHARED_LIBRARY)

Application.mk配置主要写编译平台和版本,但是基本不用写版本,只需要写平台即可.

eg:

APP_ABI := armeabi armeabi-v7a x86 mips

APP_ABI := alll 表示所有平台都支持

openssl静态编译则需要(libcrypto.a,libssl.a):

android6.0之后必须要静态编译openssl库,不然会crash。

编译静态编译需要的.a文件:

第一种方法(自己编译):

  • 配置android脚本步骤同动态编译
  • 可以利用github上面有的项目OpenSSL1.0.1cForAndroid
  • 修改crypto文件夹下的Android.mk文件, 在#target对应的include修改
    include$(BUILD_SHARED_LIBRARY)------->include $(BUILD_STATIC_LIBRARY)
  • 修改ssl文件夹下的Android.mk文件,在#target对应的include修改
    include$(BUILD_SHARED_LIBRARY)------->include $(BUILD_STATIC_LIBRARY)
  • 修改apps文件夹下的Android.mk文件,添加 LOCAL_LDLIBS += -lz
  • cd 到工程目录
  • 执行命令ndk-build(同样是在application中配置平台)
  • 在工程目录的obj文件夹下可以找到 libcrypto.a,libssl.a

第二种方法(直接下载):

这里只有4个平台的.a文件以及openssl的头文件声明

静态编译的步骤(eclipse):

  • 在eclipse上面建立一个新的项目。或者在原有项目中也可。
  • 将自己写的.c和.h以及android.mk,Application.mk放入jni目录中
  • 将得到的.a文件按平台目录不同分别放在自己项目的jni目录下。
  • 将openssl的头文件放入项目中,具体的放置的路径可以配置(openssl项目中有include目录下)
  • 配置android.mk,Application.mk文件
  • cd 到工程目录
  • 执行ndk-build命令(如果在cygwin中执行配置了命令,则根据自己配置的命令执行,如$NDK_BUILD)
  • 得到静态编译的so文件。

eg: 假设我要编译一个用openssl的so,so的名称为zty
则android.mk配置可以写成:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libcrypto     LOCAL_SRC_FILES := libcrypto.ainclude $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE := libssl      LOCAL_SRC_FILES := libssl.ainclude $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE    := ztyLOCAL_C_INCLUDES := $(LOCAL_PATH)/../openssl/include#调用静态库LOCAL_STATIC_LIBRARIES += libcrypto libsslLOCAL_LDLIBS += -llogLOCAL_SRC_FILES += encryptkey.c base64.cinclude $(BUILD_SHARED_LIBRARY) 
0 0
原创粉丝点击