Android JNI调用(二)

来源:互联网 发布:淘宝应用开发者平台 编辑:程序博客网 时间:2024/05/16 19:50


       生成java程序与c程序的接口文件

  谈到这里,自然就会联想到是c语言的。h文件了,现在的问题在于如何从。java文件生成我们需要的。h格式的c/c++文件。答案就是javah这个小工具基本上所有的jdk都会提供:

  javah -classpath "java类的地址" <你的java模块位置>

  利用javah就可以很容易地将JniModule。java代码的native标记的部分转换为c/c++的。h文件中定义的导出函数。

  以下是偶用于测试的makefile,相信懂makefile语法的朋友可以很容易就看明白偶在做什么,

  为了实验能够非常“精确”地进行,在这个makefile中的全部路径都采用了绝对路径,其实用相对路径也是可以的。

java代码:
  1. CC=arm-none-linux-gnueabi-gcc

  2. LD=arm-none-linux-gnueabi-ld

  3. MV=mv

  4. JH=javah

  5. JHFLAGS=-classpath "/home/wayne/works/workspace/JniTest/bin"

  6. LDFLAGS=-T "/home/wayne/CodeSourcery/Sourcery_G++_Lite/arm-none-linux-gnueabi/lib/ldscripts/armelf_linux_eabi.xsc" -shared

  7. CFLAGS=-I. -I/home/wayne/works/workspace/JniTest/jni/include -I/home/wayne/works/workspace/JniTest/jni/include/linux -I/home/wayne/works/workspace/JniTest/jni -fpic

  8. all: libaaaa.so
  9. com_hurraytimes_jnitest_JniModule.h:

  10. $(JH) $(JHFLAGS) com.hurraytimes.jnitest.JniModule
  11. aaaa.o: aaaa.c com_hurraytimes_jnitest_JniModule.h
  12. $(CC) $(CFLAGS) -c -o aaaa.o aaaa.c

  13. libaaaa.so: aaaa.o
  14. $(LD) $(LDFLAGS) -o libaaaa.so aaaa.o libcutils.a
  15. $(RM) ../libs/armeabi/libaaaa.so
  16. $(MV) libaaaa.so ../libs/armeabi/
  17. clean:

  18. $(RM) *.o *.so *~
复制代码

这里需要特别提一点的,就是关于arm-none-linux-gnueabi-gcc的使用问题,这个编译器自从到了2008版本就开始琢磨着实现更加方便地“cross compiler”的功能了.以往的版本是arm-xxx-linux-gcc,就是为了编译arm-linux平台的软件的,如果你的芯片从三星的变为菲利普的,那么整条工具链就要重新编译.现在的这个2008版的为了让广大开发者(尤其是多种不同芯片平台的嵌入式开发者)的计算机里面不要安装好多套for不同芯片组的gcc工具链,弄了一个-T的参数,这里就可以让开发者使用一个gcc工具链生成不同平台和格式的可执行代码以及链接的库.虽然如此,但是偶还是觉得不大习惯,总之谢谢CodeSourcery很贴心的功能,让偶花了半个多小时在琢磨和查资料,到底是什么原因导致生成的jni模块无法在android上工作.

  jni模块的打包问题
  再次声明,在android 1.5 cupcake以后的版本才可以用偶下文提到的打包方法.
  在查看了ndk的脚本以后,我才知道原来android 1.5版本在打包apk的时候,是完全可以支持直接将.so的jni库打包到apk安装包中去的,解决了偶们这种铁杆c/c++开发者开发自己的jni组件的发布问题,java脚本嘛,做个事件啥的中转就完成它的使命了.
  其实具体操作起来非常简单,在当前项目的跟目录下创建如下目录:
  /libs/armeabi
  然后把自己生成好的so库拷贝到这个armeabi目录下面即可,运行ant生成apk发布包的时候,就会自动地将/libs/armeabi目录下的so库打包到apk文件中,然后就是直接安装就好了!非常简单方便.

  关于ant里面实现jni的makefile调用的方法
  首先肯定一下,ant是个不错的东西.但是如果说它要取代makefile的地位,偶个人固执地认为很难.makefile语法简单,随手就可以敲一个,但回头看看ant的build.xml,第一眼看上去就头晕.
  xml很不错,但是就是他大爷的乱七八糟,而且居然宣称说是给人看的东西...凡事真正有些实质性的用处,用xml存储的数据(用于演示hello world之类的xml就免了),让人看起来都会头晕.
  ant采用xml作为基本输入,偶个人认为还不如仿效makefile弄一套相对简单的语法来得方便.
  好了不再发牢骚了,开始看一下,如何为android的build.xml添加ant支持的xml实现自动调用jni的makefile文件.
  以下是偶用ant来编译jni模块的xml,稍加修改就可以用于开发和实验中,把这些加到</project>之前就可以了:

java代码:
  1. <target name="mk" >

  2. <exec dir="./jni" executable="make" os="Linux" failonerror="true">
  3. </exec>
  4. </target>
  5. <target name="mkclr" >
  6. <exec dir="./jni" executable="make" os="Linux" failonerror="true">
  7. <arg line=" clean" />
  8. </exec>
  9. </target>
复制代码

       使用方法就是ant mk和ant mkclr一个是相当于调用make,另一个是相当于调用make clean。其余的操作都放到makefile里面去了。
0 0