NDK工具直接使用和分解使用

 转载地址 

http://blog.csdn.net/rozenix/article/category/787011

 

I.NDK配置和基本使用

  下载解压后即可使用。关键是不同版本的NDK开放的API不同,常用的是 r4和r5,后者面向Android 2.2+, 支持UI/图形/声音的部分C接口,还有STL的支持(遗憾的是r5中的STL没整出来)。由于我面向的平台是2.1的,所以,我用的是 r4c。

   那个NDK是真正配置好的完全支持C++(包括STL)的?网上比较有名的是Crystax NDK r4, 我用的是Mozilla 为开发Android Firefox开发而使用的NDK r4c(与Crystax类似),下载地址是:

http://ftp.mozilla.org/pub/mozilla.org/mobile/source/android-ndk-r4c-0moz3.tar.bz2

具体如何修改自己的NDK我后面再说。

1.NDK的基本使用

   这里说的基本使用,就是利用现有的NDK工具生成供SDK JAVA通过JNI调用的共享C库(lib**.so)

   以工程Helloworld为例,在工程文件夹下:

#mkdir jni

#cd jni

至少要创建Android.mk和helloworld.c,例如:

Android.mk

LOCAL_PATH := $(call my-dir)  

include $(CLEAR_VARS)    

LOCAL_MODULE := helloworld #库名称    

LOCAL_SRC_FILES := helloworld.c #源文件    

include $(BUILD_SHARED_LIBRARY) #生成共享库    

 

这是个NDK要使用的小型Makefile,更多的选项可以看 $NDK/docs/* 内的相关文档。

helloworld.c 遵从一般JNI代码的规定:

#include <jni.h>   

jstring  Java_my_helloworld_Helloworld_hello( JNIEnv* env, jobject thiz )  

{  

  return (*env)->NewStringUTF(env, "Hello World from JNI !");  

}  

  注意C++代码里面要加上 extern "C",防止C++的名称修饰使得JNI无法找到函数名。

 命名规则就是:Java_project_name_Activity_class_name_func_name.

  编译生成,采用的是NDK封装好的脚本ndk-build, 在$NDK主文件夹下,使用很简单,在工程主文件夹

下执行:(假设$NDK已经加入到$PATH)

#ndk-build

...

即可,若成功,则主文件夹的 libs/armeabi 或者libs/arm-v7te 下生成 libhelloworld.so

2.SDK中使用NDK生成的文件

  修改src/my/helloworld/Helloworld.java,使之通过JNI调用C函数:


其中先加载libhelloworld.so,再调用其内的hellow()函数。

#ant debug

重建工程

 

前面提到的都是使用现有的ndk-build建立共享库。如何建立可执行的C/C++文件?将jni/Android.mk内的

include $(BUILD_SHARED_LIBRARY) 改成include $(BUILD_EXECUTABLE) 即可。

那么,想“自由使用”工具链,比如像使用gcc/g++那样,尤其是想往Android上面移植 C/C++程序或者库时,如何才能跳出ndk-build的限制?

  I.提取Android的gcc工具链

     如果你想偷懒的话,你很幸运,有现成的 ,附件的perl脚本agcc(csdn搞不出附件,只好链接新帖子) ,即可以完成工具链的抽取和封装,可以像使用 gcc 那样使用它,它最先来自

plausible.org/andy/agcc

    不过这个是面对整个Android开发包的(包括Android/SDK/NDK的所有文件),而且没有C++/STL支持,我对它进行了修改,使它与上篇给出的ndk-r4配合,完全支持c/c++。

     如果你想自己动手,请这样做:

1.分别对

1)生成可执行文件

2)静态库

3) 动态库

4)多个源文件 的不同类型的工程使用

#ndk-build -B V=1

命令,会让ndk-build “揭露出”整个工具链的不同使用过程 ,比如上篇中的helloworld工程:

显示:

Compile thumb  : helloworld <= /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64  -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID  -Wa,--noexecstack -O2 -DNDEBUG -g  -c -MMD -MP -MF /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o.d /opt/android/android-ndk-r4c/samples/helloworld/jni/helloworld.c -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o
SharedLibrary  : libhelloworld.so
/opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic  /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/objs/helloworld/helloworld.o -Wl,--whole-archive  -Wl,--no-whole-archive  /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a  /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so    -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a -o /opt/android/android-ndk-r4c/samples/helloworld/bin/ndk/local/armeabi/libhelloworld.so

......


从这些命令记录分别提取出

1)工具的名称和位置

例如gcc/g++工具是 arm-eabi-gcc/g++,位置是 /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/。。

2)工具相关选项和参数

交叉编译时,最重要的就是编译工具的相关参数设置,以及从环境中提取的文件(头文件夹,链接文件,库文件..)。下面的从上面提取的相关参数就不用我解释了吧?(如果不熟悉这些的话,真的不应该直接从Android上手学交叉编译,道理你们懂的。。)

CC = arm-eabi-gcc

CFLAGS/CXXFLAGS ="-fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums  -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64"

CPPFLAGS ="-I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -I/opt/android/android-ndk-r4c/samples/helloworld/jni -DANDROID "

CXX =arm-eabi-g++

LDFLAGS = "-nostdlib -Wl,-soname,libhelloworld.so -Wl,-shared,-Bsymbolic  -Wl,--whole-archive  -Wl,--no-whole-archive  /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a  /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libc.so /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/libm.so    -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/libgcc.a"

3)工具的使用过程

  主要是面对不同的源文件(.c/.cpp/.o/.h...),以及不同的目标(生成什么?.o/.exe/.s...),工具的使用过程和参数都是不同的,比如上例:

.c-->.o

$CC $CPPFLAGS $CFLAGS helloworld.c -c -g -o helloworld.o

仅仅 预处理-->编译,未链接

然后

.o-->.so

$CC $LDFLAGS helloworld.o -o libhelloworld.so

完成链接

4)大家可以查看其他几类情况,使用的工具和参数各不相同。


II.直接使用工具链

  提取出了工具链,弄清其不同参数和工作流程后,就可以自己指明使用了。首先将工具加入$PATH,然后,例如编译如下的两个全面测试C++功能的.cpp文件,要求ahoo.cpp -->libahoo.so(动态库);a.cpp+libahoo.so --->a(程序):

ahoo.h


ahoo.cpp

a.cpp


命令就是:(都是先编译,再链接,注意参数的区别)

1)ahoo.cpp--->ahoo.o a.cpp-->a.o

arm-eabi-g++ ahoo.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o ahoo.o

 

arm-eabi-g++ a.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o a.o


2) ahoo.o -->libahoo.so

arm-eabi-gcc ahoo.o -nostdlib -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a -o libahoo.so

 

3) a.o -->a

arm-eabi-gcc a.o -nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtend_android.o /opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib/crtbegin_dynamic.o -o a -lahoo -L./

  你是什么感觉呢,不觉得太长太麻烦了吗?何苦呢?何必呢?所以我才将所有的内容都封装在agcc 内的啊,你难道不想也这样做吗?(尤其是对程序或者库进行 ./configure 的时候!),上面的例子,直接用我的agcc 的话(先将包含arm-eabi-*的路径加入$PATH

#agcc ahoo.cpp -shared -o libahoo.so

Compile Thumb++    :ahoo.cpp    ===> ahoo.o

...

Link ARM shared lib    : ahoo.o     ====> libahoo.so

...

#agcc a.cpp -o a -lahoo -L./

Compile Thumb++    :a.cpp    ===> a.o

....

Link ARM executable    : a.o     ====> a

...

# file a
a: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
#file libahoo.so
libahoo.so: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped

#arm-eabi-readelf -d a
Dynamic section at offset 0x132cc contains 23 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libahoo.so]
 0x00000020 (PREINIT_ARRAY)              0x1c2a4
 0x00000021 (PREINIT_ARRAYSZ)            0x8

.................

搞定!现在你也可以从自己的NDK出发提取组合自己的工具链了吧

 

Android中提取的工具链搭建好之后:

I.使用工具链移植c/c++程序或库
  这类的程序的标准生成流程都是 :./configure -->make;make install 。想往Android上移植该怎么办?
1.(若需)修改代码
  前面说到Android的C库不是POSIX兼容的,很残。若程序/库需要Android没有的内容或者不开放C接口的内容,那就悲剧了,你只有想法子改代码了。比如想移植 alsa-lib,它使用了SYS V SHM(内存共享功能),这个Android没有,有人质疑为何没有,Google官方回答:“Sorry!But NO!”这样的话,只有设法在代码内移除这个需求...
2.(若需)修改工程
  如果原工程没有跨平台支持的话,估计要修改configure,Makefile等文件才行。有两种情况:
1)如zlib,在当前机器上直接./configure --prefix=/data/local,再修改生成的Makefile,将其中的CC=gcc RANLIB=ranlib LD=ld 改成 CC=agcc RANLIB=arm-eabi-ranlib LD=arm-eabi-ld ... 改完工具就可以直接make了。

2)如libffmpeg,还有另一条路(有时这是最后一条路 ):如果你够强,直接利用Makefile.am(Makefile的来源文件)写出工程的Android.mk文件,建立标准的NDK工程,利用ndk-build完成一切。(我讨厌这招,因为很费事,难成功)
3.直接上
  若你够幸运,前面两个都不需要的话(所以我非常喜欢freedesktop.org 提供的工程,非常规范全面),以下的一条命令就行了:
#CC=agcc CXX=agcc LD=arm-eabi-ld RANLIB=arm-eabi-ranlib /
PKG_CONFIG_LIBDIR=/data/local/lib/pkgconfig:/data/local/share/pkgconfig/ /
    ./configure /
    --prefix=/data/local /
    --host=arm-eabi-linux /
    --enable-malloc0returnsnull /
    --enable-shared

这里有关键几项,
1)CC=agcc 则常见的CFLAGS,CPPFLAGS,LDFLAGS等变量都不用提供了,都在agcc里面。
2)PKG_CONFIG_LIBDIR ,当前的工程所需(若需)的库文件的.pc(库的描述文件)在哪个文件夹下面一定要指明,且不要用PKG_CONFIG_PATH, 后者会先找主机里面的库(比如主机的/usr/lib/之类的),再找目标环境里的。
3)prefix, 目标环境的路径。一般默认的是/usr/local或者/usr, 所以一定要改成目标环境的文件夹前缀,此处是 /data/local
4)host ,指的是目标平台,也可以写成 arm-unknown-linux等,不过一定要确认configure脚本能认识这个“型号”,不然会产生问题(拒绝生成动态库等等)
5)--enable-shard, 不是所有的configure默认生成动态库(我就碰到过,比如jpeg62),其他的选项类似。
6)还有,有的工程的configure方式 很特别(比如openssl和原版X11),但是大体都可以仿照以上解决。(关键是让configure找到所需的工具链,找到所需的环境以及文件,并通过测试,成功生成Makefile)

接下来,除非编译出错(这就是上面两个“若需”的工作),直接
#make;make install
就行了。


II.如何使用/运行编译的成果?
1.基本使用
  收先你要有root权限,可以参考我写的XT800 MOTO的刷机经历 。相信大家注意到前面那个奇怪的prefix=/data/loc al 了,Android平台上即使root用户(开发者)也只是对设备的部分文件夹有权限修改,最常用的就是/data/local 和/data/bin了。而JAVA程序都在/data/data下,比如我们的Helloworld.apk安装后

#adb shell ls /data/data/my.helloworld/lib/

-rw-r--r-- system   system      13225 2011-02-28 09:17 libhelloworld.so

可见它“自带的”C库也在里面(如果有多个库,只要确保 ant 最终生成之前将所有的.so放到libs/armeabi/下即可被打包进入.apk,java程序使用时别忘了所有自带库都要load一下)还有android里面库的标准路径是/system/lib/,jni所用的自带库在/data/data/...里面自己能找到,那么C/C++程序呢?要放到允许放的地方去。比如我们上篇的 libahoo.so 和 a
#adb push libahoo.so /data/local/lib
#adb push a /data/local
#adb shell

进入android 设备的shell:
##ls

tmp
pds
cdrom
sqlite_stmt_journals
config
cache
sdcard
d
etc
system
sys
sbin
proc
init_prep_keypad_ttnm.sh
init.rc
init.mapphone_cg.rc
init.goldfish.rc
init
default.prop
data
root
dev

##ps

.....
system    1503  1169  122740 14612 ffffffff afe0d984 S com.motorola.process.system
app_33    1549  1169  121964 14556 ffffffff afe0d984 S com.android.alarmclock
app_51    1557  1169  121632 14024 ffffffff afe0d984 S com.motorola.firewall
app_54    1563  1169  121464 14260 ffffffff afe0d984 S com.motorola.extdisp
app_21    1611  1169  128052 15704 ffffffff afe0d984 S com.android.vending
app_32    1622  1169  123528 14428 ffffffff afe0d984 S com.motorola.apncontrol
app_3     1632  1169  133956 14700 ffffffff afe0d984 S com.hoho.campage
app_48    1648  1169  130216 15652 ffffffff afe0d984 S com.cooliris.media
app_81    1723  1169  123436 15032 ffffffff afe0d984 S com.moto.mobile.appstore
app_1     2507  1169  145004 26464 ffffffff afe0d984 S com.google.android.apps.maps
app_15    2559  1169  122940 16352 ffffffff afe0d984 S android.process.media
dhcp      2691  1     820    428   c00d4b28 afe0d7fc S /system/bin/dhcpcd
app_38    2738  1169  121404 14336 ffffffff afe0d984 S com.svox.pico
app_73    2745  1169  123112 15672 ffffffff afe0d984 S com.eshore.android
root      2770  1148  708    328   c006cb7c afe0d62c S /system/bin/sh
app_92    2776  1169  122612 17108 ffffffff afe0d984 S my.helloworld
root      2781  2770  860    344   00000000 afe0c75c R ps

##cat /proc/2776/maps

.....

80d00000-80d1d000 r-xp 00000000 1f:06 417        /system/lib/libmetainfo.so
80d1d000-80d1e000 rwxp 0001d000 1f:06 417        /system/lib/libmetainfo.so
80e00000-80e03000 r-xp 00000000 1f:08 1925     
  /data/data/my.helloworld/lib/libhelloworld.so
80e03000-80e04000 rwxp 00002000 1f:08 1925       /data/data/my.helloworld/lib/libhelloworld.so

80f00000-80f03000 r-xp 00000000 1f:06 275        /system/lib/hw/gralloc.omap3.so
80f03000-80f04000 rwxp 00003000 1f:06 275        /system/lib/hw/gralloc.omap3.so
....

##cd /data/local
##ls -l

-rwxrwxrwx shell    shell      458405 2011-02-28 13:04 a
-rwxrwxrwx shell    shell       76232 2009-07-31 19:08 su

drwxrwxrwx root     root       2010-12-08 19:14 mnt

drwxrwxrwx root     shell             2011-02-28 13:05 lib
drwxrwxrwx mot_tcmd shell             2011-03-01 13:04 tmp

##./a

link_image[1721]:  2786 could not load needed library 'libahoo.so' for './a' (load_library[1051]: Library 'libahoo.so' not found)CANNOT LINK EXECUTABLE
所以要把路径加进去。
##LD_LIBRARY_PATH=/system/lib:/data/local/lib ./a

link_image[1721]:  2786 could not load needed library 'libahoo.so' for './a' (load_library[1051]: Library 'libahoo.so' not found)CANNOT LINK EXECUTABLE
??因为要超级权限
##su
##LD_LIBRARY_PATH=/system/lib:/data/local/lib ./a

ahoooooooooo coming!
bagaaaaaaaaa coming!
bagaaaaaaaaa dying!
ahoooooooooo dying!
Horaaaaaaaaaaa
Woraaaaaaaaaaaa
sizeof hana:100
sizeof hana:100
libahoo.so:--exception.runtime_error.string:    --
libahoo.so:--exception.catch.string:    --You are Foooooooooyoooooooed!
a    :--string:   
这下总行了。


2.给SDK使用

  说实话,在Android设备上运行c程序,有何意义?最常用的还是移植c库给java使用,比如下面这位的工作就很典型:

abitno.me/compile-ffmpeg -android -ndk

Android提供的解码功能有限,他将ffmpeg库移植到Android上成为libffmpeg.so,开放JNI接口供上层JAVA UI使用,其结果就是一个新的Android播放器。而移植一个库的过程如上所述两类:编写Android.mk 利用ndk-build创建libdep.so;或者使用agcc直接生成lib.so;然后再写一个JNI接口层libinterface.so库(除非你直接在原工程内写好接口);放到Android工程的./libs/armeabi里,最后在java内调用接口;要确保最终的.apk内包含所需的自带库。
  以下就是我写的一个底层库-->接口库-->java的示例,可以参考:

#android create project -p ./ -t 4 -n Ahoo -k ore.ahoo -a Ahoo

#cat src/ore/ahoo/Ahoo.java

#cat res/values/styles.xml

(现在不清楚有什么办法让单个Android.mk生成多个动态库,大家可以试试)

#cat jni/dep.h

 

#cat jni/dep.cpp

#cat jni/ahoo.cpp

 

分别编译(也可以用ndk-build):

#cd jni

#agcc dep.cpp -shared -o libdep.so -llog
Compile Thumb++    :dep.cpp    ===> dep.o
arm-eabi-g++ dep.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o dep.o
Link ARM shared lib    : dep.o     ====> libdep.so
arm-eabi-gcc dep.o -nostdlib -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a -o libdep.so -llog

#agcc ahoo.cpp -shared -o libahoo.so -ldep -L./ -llog
Compile Thumb++    :ahoo.cpp    ===> ahoo.o
arm-eabi-g++ ahoo.cpp -I/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/include -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DNDEBUG -mthumb-interwork -march=armv5te -mtune=xscale -msoft-float -mthumb -fpic -fPIC -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi -Wa,--noexecstack -Os -O2 -c -o ahoo.o
Link ARM shared lib    : ahoo.o     ====> libahoo.so
arm-eabi-gcc ahoo.o -nostdlib -Wl,-shared,-Bsymbolic -Wl,--whole-archive -Wl,--no-whole-archive -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/android-ndk-r4c/build/platforms/android-8/arch-arm/usr/lib -lc -lm /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libstdc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/arm-eabi/lib/libsupc++.a /opt/android/android-ndk-r4c/build/prebuilt/linux-x86/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a -o libahoo.so -ldep -L./ -llog

#ls

ahoo.cpp  dep.cpp  dep.h  libahoo.so  libdep.so

#cd ..

#cp jni/lib* libs/armeabi/

#ant debug

........

BUILD SUCCESSFUL
Total time: 3 seconds

#adb install bin/Ahoo-debug.apk
1663 KB/s (188420 bytes in 0.110s)
    pkg: /data/local/tmp/Ahoo-debug.apk
Success

 

发布了8 篇原创文章 · 获赞 4 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章