Android NDK引用预编译的动态链接库

NDK里有个例子: android-ndk-r10/samples/module-exports/jni
一看就懂了

———————————————————————————–

从r5版本开始,就支持预编译的库(共享和静态). 也就是说在你的应用中,可包含和使用 预先编译的库。

这个功能的用处
1. 你想分发你自己的库给第3方 NDK开发者,但不想把源码给他们
2. 你想使用自己的预编译的库 来加速项目的Build过程。

声明一个预编译的库模块
每个预编译的库,都必须声明为一个独立的模块 给ndk build系统。

目录结构

mylib
   --Android.mk
   --libfoo.so

Android.mk的内容

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)

注意事项
1. 每个预编译的模块都必须有一个名字, 比如上面取的名字是 foo-prebuilt
模块 名字 可以跟 预编译的库的名字 不一样(比如库的名字是 libfoo, 模块的名字是 foo-prebuild)
2. 设置 LOCAL_SRC_FILES 为你提供的预编译库的 路径。注意,这个路径 是相对于 LOCAL_PATH的。 据说也在 LOCAL_PATH/lib 目录里找源so.

另外: 如果你提供的库有多个ABI的版本,还要有点技巧,后面会提到。

3. 包含 PREBUILT_SHARED_LIBRARY (提供共享库) ; 或者 包含 PREBUILT_STATIC_LIBRARY(提供静态库)

在其他模块中 引用上面准备好的预编译模块
只需添加LOCAL_SHARED_LIBRARIES(或者 LOCAL_STATIC_LIBRARIES)声明 到你的 Android.mk中就行了

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

LOCAL_MODULE := foo-user
LOCAL_SRC_FILES := foo-user.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
#LOCAL_LDLIBS := -lm -llog

include $(BUILD_EXECUTABLE)

唯一要注意的是,引用 模块名(foo-prebuilt), 而不是库名(libfoo)

为预编译的库 输出头文件
在实际应用中, foo-user.c会依赖于 同库文件一起分发的头文件(foo.h)中声明的函数或变量
也就是说,在 foo-user.c 将会有如下代码

#include <foo.h>

构建你的foo-user模块时,必须提供 预编译模块的 头文件 以及 头文件的包含路径 给编译器。

假设头文件爱你 放在 预编译模块目录下的 include 目录, 我们可以在预编译模块的Android.mk中使用export

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include

include $(PREBUILT_SHARED_LIBRARY)

LOCAL_EXPORT_C_INCLUDES 可以让 别的引用模块 找到 适合的头文件
别的引用模块,将在 自己的 Android.mk里用 LOCAL_C_INCLUDE 来找(好像不用声明这个, LOCAL_LDFLAGS也不用)

多种ABI

armeabi   目标CPU是ARM v5 TE或者之后的架构
armeabi-v7a 目标CPU是 ARM v7或者之后的架构
x86      
mips

需要修改 预编译模块里定义的 LOCAL_SRC_FILES

 LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。