1 .前言
Andorid是支持C++库的,libc++ 的共享库为 libc++_shared.so,静态库为 libc++_static.a
静态库
如果应用的所有原生代码均位于一个共享库中,这样可让链接器最大限度内联和精简未使用的代码,使应用达到最优化状态且文件最小巧。在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。静态库对函数库的链接是放在编译时期完成的。动态库
*动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。
在使用时避免自己使用的so库与其他第三方的so库冲突,不然只有在程序运行到的时候才会发现异常。
1.1 在Android中使用ffmpeg的so库
这里Cmake的 gradle配置可以参考上篇
github代码直通车 里面的ffmpegtest 应用
1.1.1 首先先复制so库和提供的头文件
1.1.2 CMkeLists修改
cmake_minimum_required(VERSION 3.4.1)
# 设置生成的so动态库最后输出的路径
# set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
# 支持C++11标准和GNU扩展特性
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
# 1. 定义so库和头文件所在目录,方面后面使用
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)
message("当前cmakel路径: ${ffmpeg_lib_dir}")
# 2. 添加头文件目录
include_directories(${ffmpeg_head_dir}/include)
# 3. 添加ffmpeg相关的so库
add_library( avutil
SHARED
IMPORTED )
set_target_properties( avutil
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavutil.so )
add_library( swresample
SHARED
IMPORTED )
set_target_properties( swresample
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswresample.so )
add_library( avcodec
SHARED
IMPORTED )
set_target_properties( avcodec
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavcodec.so )
add_library( avfilter
SHARED
IMPORTED)
set_target_properties( avfilter
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavfilter.so )
add_library( swscale
SHARED
IMPORTED)
set_target_properties( swscale
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libswscale.so )
add_library( avformat
SHARED
IMPORTED)
set_target_properties( avformat
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavformat.so )
add_library( avdevice
SHARED
IMPORTED)
set_target_properties( avdevice
PROPERTIES IMPORTED_LOCATION
${ffmpeg_lib_dir}/libavdevice.so )
# 查找代码中使用到的系统库
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# 配置目标so库编译信息
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
ffmpeg_lib.cpp
)
# 指定编译目标库时,cmake要链接的库
target_link_libraries(
# 指定目标库,native-lib 是在上面 add_library 中配置的目标库
native-lib
# 4. 连接 FFmpeg 相关的库
avutil
swresample
avcodec
avfilter
swscale
avformat
# Links the target library to the log library
# included in the NDK.
${log-lib} )
1.1.3 jni所交互的c++文件 ffmpeg_lib.cpp
在这里调用ffmpeg的版本并显示
#include <jni.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavcodec/jni.h>
}
/**
* 拿到 ffmpeg 当前版本
* @return
*/
const char *getFFmpegVer() {
return av_version_info();
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_hugh_ffmpegtest_MainActivity_getFFmpegVersion(JNIEnv *env, jclass type) {
return env->NewStringUTF(getFFmpegVer());
}
1.1.4 在Acitivity的使用
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView ffmpegVer = findViewById(R.id.ffmpeg_ver);
ffmpegVer.setText("当前 FFmpeg 版本为:" + getFFmpegVersion());
}
/**
* @return 返回当前
*/
public native static String getFFmpegVersion();
}
1.2 在Android中使用ffmpeg的.a库
具体操作都是和用.so一样,只有CMakeLists.txt脚本需要更改
确保所指定的路径(库和头文件)都对就行了,就能一把过了
#指定 Cmake 最低版本
cmake_minimum_required(VERSION 3.4.1)
#找到包含所有的cpp文件
file(GLOB allCpp *.cpp)
#打印当前 cmakeLists 的路径
message("当前cmakel路径: ${CMAKE_SOURCE_DIR} \n cpu架构:${CMAKE_ANDROID_ARCH_ABI}")
add_library(
ffmpeg_lib
SHARED
${allCpp})
find_library(
log-lib
log)
# 引入FFmpeg的头文件
include_directories(${CMAKE_SOURCE_DIR}/include)
# 引入FFmpeg的库文件,设置内部的方式引入,指定库的目录是 -L 指定具体的库-l
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/${CMAKE_ANDROID_ARCH_ABI}")
target_link_libraries(
ffmpeg_lib
avformat avcodec avfilter avutil swresample swscale
${log-lib})
版权声明:本文为qq_38366777原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。