一.使用gcc打包so
将文件Hello.c编译成一个动态库:libHello.so,执行命令如下:
$ gcc Hello.c -fPIC -shared -o libHello.so
-shared: 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接,相当于一个可执行文件;
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
二.使用cmake
set_target_properties(util PROPERTIES output_name "test")
使用以上两种方法都有一个问题,
gcc生成的so文件并不知道是哪个cup架构下的
cmake在mac上生成的动态链接库,是dyilb文件,不是so文件
所以
三. 使用android studio生产各个cpu架构下的so文件
1. 将c文件放入main/cpp文件夹中
image.png2. 在CmakeLists.txt中进行进行配置
使用add_library指定
- so库的名字
- 生成so库的名字
add_library(
LameMp3
SHARED
src/main/cpp/LameMp3.c ${SRC_LIST})
3. 在build中指定生产哪些cup架构下的so文件
ndk{
//abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a','arm64-v8a'
abiFilters 'armeabi-v7a','arm64-v8a'
}
4. 生产so文件
点击assebleDebug或者assebleRelease,在build/cmake文件夹下生成相应的so文件
image.png
5.注意
-
头文件要使用include_directoties 引入,此时使用在.c文件中引入头文件可以直接使用include<>,可以不使用相对路径include" "
-
在cpp中引入c文件时,会报错:undefined reference to method,此时需要添加extern "C",如下
参考
#include <stdio.h>
int add(int a, int b);
#include "csapp.h"
int add(int a, int b)
{
return a + b;
}
extern "C"
{
#include "csapp.h"
}
int funcion()
{
return add(1, 2);
}
6. 额外
通常我们的会编写相应的java文件去调用so库,java文件最好也写成java包的形式
jar的位置在(android studio 版本 3.6.1)build/compile_library_classes
不过 其实在build/outputs/aar中生成的aar文件中,已经有了so文件和编译后的java文件,所以直接导出aar文件,供其他项目使用行了
网友评论