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函数库