android 第三方动态库,Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植...

获取符号地址。这是插件式程序的必备方式。

1. C++大型程序常见的模块组织方式:

不少C++大型程序以如下方式设计:

1.

有一个主程序块,此程序块通常作用是读取配置文件,并根据配置文件动态加载以插件形式提供的功能模块。(即dlopen(插件))

并维护主循环,每次循环中依次调用每个插件中的某功能(dlsym(符号)并运行)。

在退出时,使用dlclose()

将各插件移出内存并退出主循环。

2.

不同插件同样利用配置文件维护他们所用到的自有模块。(dlopen, dlsym)

3.

如有必要,各插件以动态库的形式共同使用某模块(尤其是第三方模块)。

(使用动态链接,系统加载的方式)

例如:

某程序以如下方式构建:

1.

核心程序为一个应用程序,此应用程序主要通过分析配置文件,决定加载哪些插件。同时,它维护一个循环,每个循环中调用插件的特定符号(update)。

2.

插件包括:音频库,文件系统,动作分析系统等。同时,各个游戏逻辑也作为插件存在。即从大厅进入游戏,其实就是替换一些插件。

3.

游戏模块依赖于引擎A。(以动态链接,系统加载方式使用)

这样,在Linux下,可以将引擎以及底层库放置于LD_LIBRARY_PATH制定位置。整个软件可正常运行。

2. Android

下对NDK动态库的使用:

Android下,对于动态加载的库(dlopen(lib)),使用绝对路径就可以解决问题。

对于动态链接(系统加载)的动态库,因为没有LD_LIBRARY_PATH方式,则可以采用在Activity的静态模块中使用System.LoadLibrary()方式提前加载于内存空间。

static

{

System.loadLibrary("gnustl_shared");

System.loadLibrary("testcplus");

System.loadLibrary("hello-jni");

}

3. 复杂情况下NDK动态库的组织:

使用上面所说的方法,可以解决非常简单的动态加载的动态库。但对于比较复杂的动态库。则有很多问题。

例如:某些动态库有很多全局变量,且包含一些状态信息。

而Activity在onDestory()后,进程并未完全退出。此时,动态库依然存在于内存之中。此时,再次运行应用程序。全局变量和状态还是使用之前的值。这会对逻辑造成很大困难。

于是采用如下方式:

首先:Java程序使用System.LoadLibrary()仅调用C++库(libgnustl_shared.so)以及一个非常干净简单的动态库A。

此动态库A,提供2个主要功能。Init(),

UnInit().

在Init()中,它作两件事:

1. 采用dlopen()方式将所有动态链接(系统加载)的库(如上面所说引擎)加入内存(关键点)

2. 采用dlopen()方式将需要dlopen() 的模块(如游戏逻辑)加入。

在UnInit()中。依次dlclose();

其次,动态库A所dlopen()的游戏逻辑动态库,直接使用函数名而非dlopen,dlsym的方式使用符号。这样,Linux下的代码,就不需要做任何修改即可。

在NDK 编译游戏逻辑时,指明LOCAL_SHARED_LIBRARIES

:= 引擎。也就是说:System.LoadLibrary(A),将最简单的壳子动态库加入内存。

此壳子动态库A在onCreate()时调用dlopen将所有所需动态库加入内存(引擎,游戏)。

在onDestory()时,则dlclose(),将动态库移出内存。

而在循环中,游戏动态库被dlopen,dlsym取出相应几个有限的符号并调用。

而在这些符号内,他们直接使用引擎提供的函数。因为此时引擎已经被加载入内存。所以可以使用。

dlclose时,游戏和引擎都被移出内存。

(注:有很多游戏,但引擎只有一个,游戏使用此共同的引擎提供的函数)

第三方C++库的移植:

在开发Android大型程序时,不可避免要用到很多第三方OpenSouce.而大多数第三方库采用AutoConfig,或者CMake等特定编译工具编译。现在就说说如何利用NDK将其编译成咱们能够使用的静态库或者动态库。

现在以xiph-ogg为例,演示如何使用NDK编译这些第三方库。

0. 准备工作:

下载xiph source code.

要编译的内容是:

xiph/ogg:生成libogg.so或者libogg.a

xiph/vorbis: 生成libvorbisfile.so  libvorbis.so

或者对应.a .

1. 确定库所包含的源文件:

编译libogg.so,需要编译的源文件包括:

bitwise.c framing.c

2.组织文件和写Android.mk+Application.mk

Sam作如下目录结构:

xiph/ogg/jni/

这里包含4个文件: bitwise.c

framing.c, Android.mk, Application.mk

作Android.mk如下:注意需要填写的资源文件(两个.c)以及指定-I目录。

LOCAL_PATH

:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_ARM_MODE := arm

LOCAL_MODULE := ogg

LOCAL_SRC_FILES := bitwise.c framing.c

LOCAL_CXXFLAGS :=

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/ogg/include

#LOCAL_SHARED_LIBRARIES :=

LOCAL_LDLIBS := -llog

#include $(BUILD_EXECUTABLE)

include $(BUILD_SHARED_LIBRARY)

#include $(BUILD_STATIC_LIBRARY)

编译之:

../../../../../ndk-build -B V=1

在xiph/ogg/libs/armeabi-v7a/下生成libogg.so

libvorbisfile.so

libvorbis.so的建立也一样,Android.mk如下:

LOCAL_PATH

:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_ARM_MODE := arm

LOCAL_MODULE := vorbis

LOCAL_SRC_FILES := mdct.c smallft.c block.c envelope.c

window.c lsp.c lpc.c  analysis.c synthesis.c psy.c

info.c floor1.c floor0.c \

res0.c mapping0.c registry.c codebook.c

sharedbook.c lookup.c bitrate.c

LOCAL_CXXFLAGS :=

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/ogg/include

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/vorbis/include

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/vorbis/lib

LOCAL_LDLIBS := -lm

LOCAL_LDLIBS += -logg

#LOCAL_SHARED_LIBRARIES :=

LOCAL_LDLIBS += -llog

LOCAL_LDLIBS +=

-L/opt/Android-NDK/android-ndk-r8b/samples/xiph/NDK_Build/ogg/libs/armeabi-v7a

#include $(BUILD_EXECUTABLE)

include $(BUILD_SHARED_LIBRARY)

#include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_ARM_MODE := arm

LOCAL_MODULE := vorbisfile

LOCAL_SRC_FILES := vorbisfile.c

LOCAL_CXXFLAGS :=

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/ogg/include

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/vorbis/include

LOCAL_CFLAGS +=

-I/opt/Android-NDK/android-ndk-r8b/samples/xiph/xiph/vorbis/lib

LOCAL_LDLIBS := -lm

LOCAL_LDLIBS += -logg

LOCAL_LDLIBS += -lvorbis

#LOCAL_SHARED_LIBRARIES :=  \

LOCAL_LDLIBS += -llog

LOCAL_LDLIBS +=

-L/opt/Android-NDK/android-ndk-r8b/samples/xiph/NDK_Build/ogg/libs/armeabi-v7a

LOCAL_LDLIBS +=

-L/opt/Android-NDK/android-ndk-r8b/samples/xiph/NDK_Build/vorbis/libs/armeabi-v7a

#include $(BUILD_EXECUTABLE)  \

include $(BUILD_SHARED_LIBRARY)

#include $(BUILD_STATIC_LIBRARY)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值