给Android增加分享库.so文件

Android工程文件夹中,我们可以通过jni机制来调用c/c++编写的本地共享库,例如libtest.so

在java文件中声明一个静态的调用,和共享库中要调用的函数

test.java中

static{

system.loadlibrary("test");

}

static native int test(int i);

相应在相关的c/c++ 文件中按照jni的编写规则编写即可,android自己增加了一个当loadlibrary时会调用jni_onload , jni_unload函数,这个不是重点。

我要提供的是so文件交叉编译的方法。

android提供了ndk及相关mk文件的写法用来给编程人员编写c/c++本地文件,但我看了一下并不习惯这种编译方式,懒得去弄明白。所以决定还是按照原来的交叉编译方式进行

1.首先在源码中寻找/prebuild/linux-x86/tooltrain/arm-eabi-4.x.1/bin/这个目录下的编译文件,在~/.bashrc中将编译使用的gcc, g++, ar等定义相应变量cc,cpp,ar为arm编译器,并在make file中使用相应变量来编译

2.在编译so时要加上 -nostdlib 参数,不然系统会去链接标准库发生ld的错误

例如: $CPP -shared -nostdlib -fpic -o libtest.so -c test.o (test.c 生产test.o文件时需要-I 源码中的dalvik/libnativehelper/include/nativehelper文件夹,不然会因缺少头文件导致编译失败)

3.将生产的so文件拷贝到工程 /libs/armeabi/ 下,调用即可

解释几个基本概念:

1. 在linux中用ar -cvr -o libabcd.a ab.o cd.o 编译会生成.a文件,这个称为静态库或归档库,可以在编译的时候加入.a一起编译,(gcc -o main main.o -L. -labcd)运行时程序会copy静态库中的代码段。-L后面跟静态库所属目录,-l后为静态库名称,系统会自动过滤掉lib 和.a

2. .so文件生成 gcc -shared -fpic -o libabcd.so libabcd.a

so文件为共享库,相当于dll,在运行时要调用时才去加载共享库中代码 可执行文件编译方式与.a类似。

3.为什么要加入nostdlib,因为android没有用linux的libc库,而是使用自己的c函数库

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwssjx.html