首页 > 解决方案 > 如果 renderscriptTargetApi > 20,渲染脚本不会生成 librs.xx.so

问题描述

我正在使用渲染脚本进行音频 dsp 处理。在我决定将renderscriptTargetApi版本从 19 升级到 24 以尝试以向后兼容的方式使用更新的渲染脚本 API 之前,它运行良好。

编译没有问题,但是在运行时,logcat显示这样的错误

05-31 19:40:23.097 8661-8734/com.example.audio.test E/RenderScript: 无法打开共享库 (/data/user/0/com.example.audio.test//lib/librs.xx .so):dlopen 失败:找不到库“libRSSupportIO.so”

如果我有renderscriptTargetApi19 或 20,我的 apk 有librs.xx.so并且没有错误。如果我将它撞到 21、23 或 24,librs.xx.so则不会生成,因此我有这个运行时错误。

我正在通过 NDK 即 C++ 使用渲染脚本。也使用 CMake。我找不到通过 NDK 使用渲染脚本支持库的说明。所有说明都假定支持库是通过 Java 使用的。

这是从build.gradle

    ndk {
        abiFilters 'armeabi-v7a', 'x86'
    }

    renderscriptTargetApi 24
    renderscriptSupportModeEnabled true
    renderscriptNdkModeEnabled true

CMakeLists.txt

add_library (dsp SHARED
  ${SRC_PATH}/dsp.cpp
  ${SRC_RS_PATH}/xx.rs ${SRC_RS_GENERATED_PATH}/ScriptC_xx.cpp)

target_compile_options(dsp PRIVATE 
  -std=c++11 -stdlib=libc++ -fno-rtti -fexceptions -Ofast)

target_link_libraries(dsp RScpp_static dl ${log-lib})

这是xx.rs

#pragma version(1)
#pragma rs java_package_name(com.example.audio)
#pragma rs_fp_relaxed

float RS_KERNEL my_kernel(float in, uint32_t x) {
    // ...
}

这就是从 C++ 调用内核的方式

sp<RS> rs = new RS();
rs->init(app_cache_dir);

sp<const Element> e = Element::F32(rs);
sp<const Type> t = Type::create(rs, e, 44100*10, 0, 0);

sp<Allocation> inAlloc = Allocation::createTyped(rs, t);
inAlloc->copy1DFrom(input);

sp<Allocation> outAlloc = Allocation::createTyped(rs, t);

ScriptC_xx *script = new ScriptC_xx(rs);
script->forEach_xx(inAlloc, outAlloc);

outAlloc->copy1DTo(output);

如您所见,这是渲染脚本的基本使用场景。它适用renderscriptTargetApi于 19 或 20。如果我升级版本,构建仍然成功,但librs.xx.so不会生成文件。在运行时,我们看到上面提到的关于这个 .so 文件的错误。

我在这里想念什么?我尝试操纵我minSdkVersion认为与renderscript target api无关的我。它没有帮助。

如何以向后兼容的方式从 NDK 使用更新的渲染脚本 API?任何帮助表示赞赏。

回购以重现该问题

https://github.com/rpattabi/renderscript-ndk-cmake

我已经提交了关于 Android 构建系统的错误报告:https ://issuetracker.google.com/issues/109578956

标签: androidandroid-ndkandroid-support-libraryrenderscriptandroid-rendering

解决方案


推荐阅读