【问题标题】:OpenCL in Android StudioAndroid Studio 中的 OpenCL
【发布时间】:2016-03-19 17:02:28
【问题描述】:

我想在 Android Studio 中使用 OpenCL,

我从我的 android 设备设备中抓取了 libOpenCL.so 并将其放入 jniLibs/[ABI]/

我把头文件放到jni/CL/

编辑:

我切换到 gradle-experimental:0.6.0-alpha7 并且它带来了一些其他问题,我用这个替换了第一部分:

repositories {
    libs(PrebuiltLibraries) {
        OpenCL {
            headers.srcDir "src/main/jni/CL"
            binaries.withType(SharedLibraryBinary) {
                sharedLibraryFile = file("src/main/jniLibs/${targetPlatform.getName()}/libOpenCL.so")
            }
        }
    }
}
android.sources {
    main {
        jni {
            dependencies {
                library "OpenCL" linkage "shared"
            }
        }
    }
}

现在它给出了这些错误:

C:\Users\Umut\Desktop\HelloJNI\app\src\main\jniLibs\arm64-v8a\libOpenCL.so: 添加符号时出错:文件格式错误

错误:错误:ld 返回 1 个退出状态

错误:任务 ':app:linkHello-jniArm64-v8aDebugAllSharedLibrary' 的执行失败。 构建操作失败。 链接 libhello-jni.so 时链接器失败。

“文件格式错误”是什么意思?我直接从我的安卓手机上拿了图书馆。

谁能帮我解决我做错了什么或者我应该怎么做才能解决这个问题?

由于我是android开发和gradle的新手,如果我误解了什么,请向我道歉。

.

之前使用 GRADLE EXPERIMENTAL 0.4.0 进行的尝试

使用 gradle-experimental:0.4.0 时,我将其放入我的 build.gradle 文件中:

android.sources {
    main {
        jniLibs {
            dependencies {
                library file("src/main/jniLibs/armeabi-v7a/libOpenCL.so") abi "armeabi-v7a"
                library file("src/main/jniLibs/armeabi/libOpenCL.so") abi "armeabi"
                library file("src/main/jniLibs/x86/libOpenCL.so") abi "x86"
            }
        }
    }
}

这是我在 build.gradle 中的 ndk 块:

android.ndk {
    moduleName = "openCLJni"
    cppFlags.addAll(["-I${file("src/main/jniLibs/")}".toString()])
    ldLibs.addAll(["android", "log"])
    stl = "stlport_static"
}

我尝试从我的 openCLJni.c 进行一个非常简单的函数调用:

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                              jobject thiz )
{
    cl_uint ret_num_platforms;
    cl_platform_id platform_id = NULL;
    cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    return (*env)->NewStringUTF(env, "Hello from JNI");
}

但它给了我这个错误:

错误:(65) 未定义对 `clGetPlatformIDs' 的引用

错误:任务“:app:linkArm64-v8aDebugAllHello-jniSharedLibrary”执行失败。

构建操作失败。 链接 libhello-jni.so 时链接器失败。 查看完整日志:file:///C:/Users/Umut/Desktop/OpenCLTest2/app/build/tmp/linkArm64-v8aDebugAllHello-jniSharedLibrary/output.txt

【问题讨论】:

  • 似乎错误为您指明了正确的方向。您必须添加一个共享库来链接 clGetPlatformIDs() 函数。我使用 NDK_BUILD(不是 gradle)来执行此操作,它的工作原理如下所述:developer.android.com/ndk/guides/prebuilts.html
  • 我想你应该在此处添加库:ldLibs.addAll(["android", "log"]) 其中android 指的是libandroid.solog 指的是liblog.so 用于您的#include <android/log.h> 内容。您已经为标头设置了包含路径,但没有告诉链接器任何关于 clGetPlatformIDs
  • 感谢您的回答,但是当我尝试像这样将 opencl 添加到那里时:ldLibs.addAll(["android", "log", "OpenCL"]) 它给了我这个错误:C:/Users/MYNAME/AppData/Local/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/../lib/gcc/aarch64-linux-android/4.9/../../../../aarch64-linux-android/bin/ld.exe: cannot find -lOpenCL

标签: java android android-ndk android-gradle-plugin opencl


【解决方案1】:

遇到了同样的问题,我设法解决了:

该库是为特定架构构建的,如果您没有在 gradle 构建中添加 abiFilter,那么它将尝试为所有可用架构编译和使用该库,其中大多数库不兼容,因此您可以获取文件格式错误。

解决方案是简单地为您从中获取库的架构添加一个 abiFilter。我从 Galaxy Note 5 中获得了该库。我在 gradle build 中为“armeabi”添加了一个 abiFilter 并且它有效。同样的文件也适用于“armeabi-v7a”架构。

我还注意到,您可以使用 ADB 提取该库的多个版本。我从“/system/vendor/lib64/egl”中找到并提取了 libGLES_mali.so,它也是 OpenCL Mali 库,并且能够使用运行速度更快的“arm64-v8a”架构运行 OpenCL。

您应该在正确的架构库文件夹中为您想要支持的架构拉取并添加正确的库,并使用与库架构匹配的 abiFilters 在 gradle 中创建风格。

这是我使用 gradle experimental 0.7.0 构建的 gradle 文件:

apply plugin: 'com.android.model.application'


model {

    repositories {
        libs(PrebuiltLibraries) {

            OpenCL {
                headers.srcDir "src/main/jniLibs/include/CL"
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("src/main/jniLibs/${targetPlatform.getName()}/libGLES_mali.so")
                }
            }
        }
    }

    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"

        defaultConfig {
            applicationId "com.apps.opencl_app"
            minSdkVersion.apiLevel 15
            targetSdkVersion.apiLevel 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-android.txt'))
            }
        }

        ndk {


            moduleName = "sr_native"
            CFlags.add("-I${file("src/main/jniLibs/include/CL")}".toString())
            cppFlags.add("-I${file("src/main/jniLibs/include/CL")}".toString())
            ldLibs.addAll(["log"])
            abiFilters.add("arm64-v8a")


        }

        sources {

            main {
                jni {
                    dependencies {
                        library "OpenCL" linkage "shared"
                    }
                }

            }
        }

    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'
}

【讨论】:

    【解决方案2】:

    对于现代系统,您应该使用

    adb pull /system/vendor/lib64/libOpenCL.so
    

    目前大部分教程都会告诉你使用

    adb pull /system/vendor/lib/libOpenCL.so
    

    它会工作,但我猜那个库是为 32 位系统设计的。

    【讨论】:

      猜你喜欢
      • 2015-10-15
      • 2018-02-06
      • 2018-07-15
      • 1970-01-01
      • 2017-12-07
      • 2015-10-26
      • 2016-08-16
      • 2016-02-04
      • 2017-08-07
      相关资源
      最近更新 更多