Android 在引用 FFmpeg 静态库时,出现 libavformat/hls.c:881: error: undefined reference to ‘atof’

错误信息如下:

  libavformat/hls.c:881: error: undefined reference to 'atof'
  libavformat/hlsenc.c:1233: error: undefined reference to 'atof'
  libavformat/http.c:1758: error: undefined reference to 'inflateEnd'
  libavformat/http.c:773: error: undefined reference to 'inflateEnd'
  libavformat/http.c:774: error: undefined reference to 'inflateInit2_'
  libavformat/http.c:779: error: undefined reference to 'zlibCompileFlags'
  libavformat/http.c:1535: error: undefined reference to 'inflate'
  libavformat/id3v2.c:1031: error: undefined reference to 'uncompress'
  libavformat/img2dec.c:266: error: undefined reference to 'glob'
  ...

造成这种问题的原因有三个:

  1. 有可能是在编译 FFmpeg 库时 Android API 版本太高导致,具体出错原因可以参考原文解释:

    Google have moved some of the C standard library functions like atof() from being inline functions in header files to normal functions. The latest NDKs will default to building a .so that is only compatible with the latest Android devices that have the atof() function in the device’s standard C library (libc.so). This means if you run a library on an older device that has an older version of the C library, you will get an error loading the dll as the expected atof() function will not exist.

    解决方案: 将 FFmpeg 编译脚本 Android API 版本改为 17 ,重新编译

  2. FFmpeg 库的依赖顺序错误,导致定义的符号找不到,造成编译错误。
    简单说一下编译链接工作原理:

  • 链接器从左往右扫描目标文件和静态库

  • 扫描发现未解析的符号会先记住这个未解析的符号

  • 当扫描到后面的静态库时,找到了前面未解析的符号,会提取相关代码

  • 最终没有任何未解析的符号,编译链接工作完成

    既然知道工作原理了,只需要把依赖顺序写对就好:

avfilter avformat avcodec avutil swresample swscale
  1. 因为是引入静态库,FFmpeg 需要依赖 zlib 库,所以在链接 FFmpeg 静态库时,需要加入 zlib 库
target_link_libraries(...
        avfilter avformat avcodec avutil swresample swscale
                      z)

你可能感兴趣的:(Android 在引用 FFmpeg 静态库时,出现 libavformat/hls.c:881: error: undefined reference to ‘atof’)