【问题标题】:Android Cmake compiler is generating .out files with extra prefixes and suffixes to the symbolsAndroid Cmake 编译器正在生成带有额外前缀和符号后缀的 .out 文件
【发布时间】:2017-10-23 13:17:27
【问题描述】:

我正在尝试将 ffmpeg 流式传输的渲染视频传输到 Android 上的表面视图。我的代码正在通过编译,但它在运行时崩溃。通过使用 nm 工具(NDK 的一部分),我检查了编译器生成的符号,发现它添加了一些特殊的前缀(如 _Z6)和后缀(例如:_JNIEnvP8_jobjectP8_jstring)。如果它仅适用于 JNI 方法,这可能是有效的。但它对 libavcodec.so 等共享对象文件中包含的函数也是如此。我在这里错过了什么吗?

NDK 版本:15.2.****(最新)

ndk {
        abiFilters 'armeabi'
    }
    externalNativeBuild {
        cmake {
            arguments '-DANDROID_PLATFORM=android-16',
                    '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static', '-DANDROID_DEPRECATED_HEADERS=ON', "-DANDROID_CPP_FEATURES=rtti exceptions"
        }
        ndkBuild {
            arguments "APP_DEPRECATED_HEADERS=true"
        }
    }

下面是 nm 工具的输出。

arm-linux-androideabi-nm -a ../.externalNativeBuild/cmake/release/armeabi/CMakeFiles/ffmpeg-jni.dir/ffmpeg-jni.cpp.o
00000000 n .ARM.attributes
00000000 r .ARM.exidx.text.JNI_OnLoad
00000000 r .ARM.exidx.text._Z12createBitmapP7_JNIEnvii
00000000 r .ARM.exidx.text._Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 r .ARM.exidx.text._Z13naGetVideoResP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z15decodeAndRenderPv
00000000 r .ARM.exidx.text._Z6finishP7_JNIEnv
00000000 r .ARM.exidx.text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 r .ARM.exidx.text._Z6naPlayP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z6naStopP7_JNIEnvP8_jobject
00000000 r .ARM.exidx.text._Z6wcslenPKw
00000000 r .ARM.exidx.text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 r .ARM.exidx.text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 r .ARM.extab.text.JNI_OnLoad
00000000 r .ARM.extab.text._Z12createBitmapP7_JNIEnvii
00000000 r .ARM.extab.text._Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 r .ARM.extab.text._Z13naGetVideoResP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z15decodeAndRenderPv
00000000 r .ARM.extab.text._Z6finishP7_JNIEnv
00000000 r .ARM.extab.text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 r .ARM.extab.text._Z6naPlayP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z6naStopP7_JNIEnvP8_jobject
00000000 r .ARM.extab.text._Z6wcslenPKw
00000000 r .ARM.extab.text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 r .ARM.extab.text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 r .L.str
00000042 r .L.str.17
00000000 r .L.str.6
0000000d r .L.str.9
00000000 b .bss
00000000 n .comment
00000000 d .data
00000000 N .debug_abbrev
00000000 N .debug_frame
00000000 N .debug_info
00000000 N .debug_line
00000000 N .debug_loc
00000000 N .debug_macinfo
00000000 N .debug_pubnames
00000000 N .debug_pubtypes
00000000 N .debug_ranges
00000000 N .debug_str
00000000 n .group
00000000 n .note.GNU-stack
00000000 r .rodata.str1.1
00000000 r .rodata.str4.4
00000000 t .text
00000000 t .text.JNI_OnLoad
00000000 t .text._**Z12**createBitmapP7_JNIEnvii
00000000 t .text._**Z12**naSetSurfaceP7_JNIEnvP8_jobjectS2_
00000000 t .text._**Z13**naGetVideoResP7_JNIEnvP8_jobject
00000000 t .text._Z15decodeAndRenderPv
00000000 t .text._Z6finishP7_JNIEnv
00000000 t .text._Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 t .text._Z6naPlayP7_JNIEnvP8_jobject
00000000 t .text._Z6naStopP7_JNIEnvP8_jobject
00000000 t .text._Z6wcslenPKw
00000000 t .text._Z7naSetupP7_JNIEnvP8_jobjectii
00000000 t .text._ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
00000000 a /Users/gopinath/repos/app_android/productionapp/app/src/main/cpp/ffmpeg-jni.cpp
         U ANativeWindow_fromSurface
         U ANativeWindow_lock
         U ANativeWindow_release
         U ANativeWindow_setBuffersGeometry
         U ANativeWindow_unlockAndPost
         U AndroidBitmap_lockPixels
         U AndroidBitmap_unlockPixels
00000000 T JNI_OnLoad
00000000 T _Z12createBitmapP7_JNIEnvii
00000000 T _Z12naSetSurfaceP7_JNIEnvP8_jobjectS2_
         U _Z13av_read_frameP15AVFormatContextP8AVPacket
         U _Z13avcodec_closeP14AVCodecContext
         U _Z13avcodec_open2P14AVCodecContextPK7AVCodecPP12AVDictionary
00000000 T _Z13naGetVideoResP7_JNIEnvP8_jobject
         U _Z14av_dump_formatP15AVFormatContextiPKci
         U _Z14av_frame_allocv
         U _Z14av_free_packetP8AVPacket
         U _Z14sws_getContextii13AVPixelFormatiiS_iP9SwsFilterS1_PKd
         U _Z15av_register_allv
00000000 T _Z15decodeAndRenderPv
         U _Z19avformat_open_inputPP15AVFormatContextPKcP13AVInputFormatPP12AVDictionary
         U _Z20av_image_fill_arraysPPhPiPKh13AVPixelFormatiii
         U _Z20avcodec_find_decoder9AVCodecID
         U _Z20avformat_close_inputPP15AVFormatContext
         U _Z21avcodec_decode_video2P14AVCodecContextP7AVFramePiPK8AVPacket
         U _Z25avformat_find_stream_infoP15AVFormatContextPP12AVDictionary
00000000 T _Z6finishP7_JNIEnv
00000000 T _Z6naInitP7_JNIEnvP8_jobjectP8_jstring
00000000 T _Z6naPlayP7_JNIEnvP8_jobject
00000000 T _Z6naStopP7_JNIEnvP8_jobject
00000000 T _Z6wcslenPKw
         U _Z7av_freePv
00000000 T _Z7naSetupP7_JNIEnvP8_jobjectii
         U _Z9sws_scaleP10SwsContextPKPKhPKiiiPKPhS6_
00000000 W _ZN7_JNIEnv22CallStaticObjectMethodEP7_jclassP10_jmethodIDz
         U __aeabi_memcpy
         U __aeabi_unwind_cpp_pr0
         U __aeabi_unwind_cpp_pr1
         U __android_log_print
         U __sF
         U __stack_chk_fail
         U __stack_chk_guard
0000001c B bitmap
00000020 B buffer
00000010 B codecCtx
00000014 B decodedFrame
00000008 B formatCtx
00000018 B frameRGBA
         U fwrite
0000002c B height
         U malloc
         U pthread_create
00000030 B stop
00000024 B sws_ctx
00000004 B videoFileName
0000000c B videoStream
00000028 B width
00000000 B window

它为 _Z14av_frame_allocv 等库定义的函数添加前缀和后缀。 (这里 _Z14 & v 是由编译器预先添加和附加的)有没有人遇到过类似的问题?有人可以指出这里发生了什么,我怎样才能让它省略额外的前缀和后缀?

【问题讨论】:

  • 到底是什么问题?由于 c++ 名称修改而添加了前缀,我怀疑它与您的应用程序崩溃有什么关系
  • 看起来我的问题是由于在同一个文件中混合了 C 和 C++ 代码而不使用 extern C。抱歉这个蹩脚的问题。本地开发新手
  • logcat 对这次崩溃有什么看法?
  • 崩溃是找不到符号_Z14av_frame_allocv。我通过将文件编译为 c 文件而不是 cpp 文件解决了这个问题。

标签: android c++ ffmpeg android-ndk


【解决方案1】:

我花了一段时间才弄清楚,因为我是原生开发的新手。问题是我结合了 C 和 C++ 代码并使用 g++ 编译器进行编译。为了让 c++ 支持方法重载,编译器附加了唯一的前缀和后缀。

解决方法是在extern C 块下导入C 头文件。或者将整个文件制作为 .c 文件并尽可能使用 gcc 进行编译。后来的解决方案对我有用。

【讨论】:

    【解决方案2】:

    将您的 C 代码包装在 extern C 块中。

    extern "C"
    {
       void foo(char);
       int bar;
    }
    

    这是为了告诉 C++ 编译器不要对特定代码进行任何名称修改。 有关名称修改的更多详细信息here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 2017-10-18
      • 1970-01-01
      相关资源
      最近更新 更多