一、使用NDK编译C++代码
1.1概述
最近需要把PC端实现的算法移植到Unity3d, 但是发现从C++算法移植到C#代码性能损失的太多了。在C++实现下,是可以做到实时的,但是移植到C#上面几乎卡的不能动了。PC端况且如此,那么Android端几乎不用想了。因此考虑将代码打包成动态库,用C#调用动态库实现高性能算法。
1.2 NDK下载与环境配置
- NDK下载: https://developer.android.com/ndk/downloads/index.html
- NDK安装:将下载的NDK解压,放置在合适的位置,我放置的位置如下图所示
- 环境配置1:在系统变量中添加NDK_ROOT, 指向NDK的目录
4.环境配置2:在Path中添加NDK_ROOT
- NDK测试:在cmd命令行中输入ndk-build,出现下面内容表示成功
1.3 NDK代码编译
网上的教程大多数是针对Java的,而我的需求主要是生成C#可以调用的动态库文件。
1.3.1 编译目录建立
在ndk的目录中的sample文件夹建立一个ExpSolver文件夹,然后建立JNI文件夹。在JNI文件夹中放置C++文件与依赖库。如下图所示:
1.3.2 mk文件配置
NDK通过mk文件来识别生成so库的安卓支持版本、生成平台、库支持等功能。
# 编译所有CPU的.so
# APP_ABI := all
# 添加几乎全平台支持 ARM-x86
APP_ABI := armeabi-v7a x86 arm64-v8a x86_64
# 最低android版本为 android-14 -> android-4.0
APP_PLATFORM := android-14
# 添加C++ STL库支持
APP_STL := stlport_static
# ------------------------------------------------------------------------------#
# 描述 : Expression Fitting Solver Config File
# 作者 :
# 时间 : 2018-12-24
#-------------------------------------------------------------------------------#
# 设置本地目录
LOCAL_PATH := $(call my-dir)
# --------------------------- 标准库支持 ---------------------------------------#
# 添加C++ stl 头文件支持
LOCAL_C_INCLUDES := $(NDK_ROOT)/sources/cxx-stl/stlport/stlport
LOCAL_STATIC_LIBRARIES := $(NDK_ROOT)/sources/cxx-stl/stlport/libs/armeabi/libstlport_static.a
# --------------------------- 第三方库支持 -------------------------------------#
# 添加Eigen3 矩阵运算库支持
LOCAL_C_INCLUDES += $(LOCAL_PATH)/Eigen
# 添加Eigen3 NNLS 求解器支持
LOCAL_C_INCLUDES += $(LOCAL_PATH)/Eigen3-nnls
# ----------------------------工程文件包含--------------------------------------#
include $(CLEAR_VARS)
LOCAL_MODULE := ExpSolver
# 包含文件设置
LOCAL_SRC_FILES := ExpSolver.cpp
# ----------------------------配置文件生成类型 ---------------------------------#
# 生成可执行文件
# include $(BUILD_EXECUTABLE)
# 生成动态链接库
include $(BUILD_SHARED_LIBRARY)
1.3.2 NDK编译
通过cmd进入到要编译的目录,调用ndk-build命令编译代码,如下图所示:
1.4 总结
网上很多的教程主要是针对java的,同时很多教程也需要用到AndroidStudio等一系列东西。对于我们这种做算法开发的,不太熟悉过多的Android环境开发方面的东西。因此单独使用NDK最为简单。当我们使用NDK时,可以直接把NDK类似CMake的编译器使用,生成多平台的动态库即可。