用ndk环境编译android可用的so库

Posted 小筱萌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用ndk环境编译android可用的so库相关的知识,希望对你有一定的参考价值。

需求:由于算法人员已经用c++写好了接口,现在要迁移到android上来,不可能让算法的代码在重新在androidstudio上在重新编写一遍,所以只能把现有的代码封装成android可调用的so库,然后利用JNI在封装成android可使用的接口

首先第一步我们来讲:如何使用ndk环境编译cpp源文件供Android调用

说明:Android上所用的so库必须在NDK环境下编译的才可以,我之前一直使用的是纯linux编译的do库,调用的时候一直报平台不兼容的错,后来才知道必须使用NDK环境编译的才可以,希望能帮助需要的人少走一些弯路,下面开始正经的了~

1)下载Android NDK,下载地址为:https://developer.android.google.cn/ndk/downloads/index.html ,目前最高的版本为android-ndk-r14b

2)将下载好的NDK随便解压缩到一个目录下,我的目录为:D:\\updatendk\\android-ndk-r14b

3)创建要编译的JNI目录,比如:D:\\NDK-Build\\jni,并将要编译的C++代码放入sourceCode文件夹下,比如:D:\\NDK-Build\\jni\\sourceCode

4)在jni目录下创建android.mk和Application.mk文件

5)将build_native.bat脚本文件也放在跟jni平级的目录中去

其中:Android.mk文件的内容如下:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS)

LOCAL_MODULE := hello_shared
LOCAL_MODULE_FILENAME := libhello
#设置可以使用C++代码
LOCAL_CPPFLAGS += -std=c++11

# 配置自己的源文件目录和源文件后缀名
    MY_FILES_PATH  :=  $(LOCAL_PATH) \\
    $(LOCAL_PATH)/../../ClientSocketEngine

MY_FILES_SUFFIX := %.cpp %.c
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)


# 配置自己的源文件目录和源文件后缀名
MY_FILES_PATH  :=  $(LOCAL_PATH) \\
                   $(LOCAL_PATH)/../../ClientSocketEngine

MY_FILES_SUFFIX := %.cpp %.c

# 递归遍历目录下的所有的文件
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
 
###################放置自己的cpp文件路径
MY_SRC_LIST = $(LOCAL_PATH)/../../sourceCode\\sayHelloWorld.cpp 
###################   

# 去除字串的重复单词
define uniq =
  $(eval seen :=)
  $(foreach _,$1,$(if $(filter $_,$seen),,$(eval seen += $_)))
  $seen
endef

# 递归遍历获取所有目录
MY_ALL_DIRS := $(dir $(foreach src_path,$(MY_FILES_PATH), $(call rwildcard,$(src_path),*/) ) )
MY_ALL_DIRS := $(call uniq,$(MY_ALL_DIRS))

# 赋值给NDK编译系统
LOCAL_SRC_FILES  := $(MY_SRC_LIST)
#头文件路径指向 
LOCAL_C_INCLUDES :=$(MY_ALL_DIRS)  

APP_ALLOW_MISSING_DEPS :=true
 
include $(BUILD_SHARED_LIBRARY)

Appication.mk的文件内容如下:

APP_STL := gnustl_static  
APP_CPPFLAGS := -frtti -DCOCOS2D_DEBUG=1 -fexceptions


build_native.bat脚本内容如下:

注意:NDK_ROOT是当前解压缩之后的ndk路径

@set "NDK_ROOT=D:\\updatendk\\android-ndk-r14b"

@set "DIR=%cd%"
@REM ... use paths relative to current directory
@set "APP_ROOT=%DIR%/.."
@set "APP_ANDROID_ROOT=%DIR%"

@echo NDK_ROOT = %NDK_ROOT%
@echo APP_ROOT = %APP_ROOT%
@echo APP_ANDROID_ROOT = %APP_ANDROID_ROOT%

@echo Using prebuilt externals
@"%NDK_ROOT%/ndk-build.cmd" 
pause

6)执行bat脚本:

成功之后会在jni平级的目录中会新增加libsobj文件夹,其中libs文件夹下就是要生成的对应android平台的libhello.so文件

so库编译成功之后就可以放入androidstudio环境中用jni调用了,调用步骤我们下篇文章继续讲述~

以上是关于用ndk环境编译android可用的so库的主要内容,如果未能解决你的问题,请参考以下文章

Linux下NDK编译出的SO库能在WIndows下的android工程直接使用么

eclipse里配置Android ndk环境,用eclipse编译.so文件

ndk编译生成so

android ndk编译so库,脚本编译ffmpeg5.0示例

如何用Android NDK编译FFmpeg

Android NDk环境配置