java - Android Studio 中的 OpenCL

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

我想在 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: error adding symbols: File in wrong format

Error:error: ld returned 1 exit status

Error:Execution failed for task ':app:linkHello-jniArm64-v8aDebugAllSharedLibrary'. A build operation failed. Linker failed while linking libhello-jni.so.

“文件格式错误”是什么意思?我直接从我的 Android 手机上获取了该库。

有人可以帮我解决我做错了什么或者我应该做什么来解决这个问题吗?

由于我是 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 block :

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");
}

但它给了我这个错误:

Error:(65) undefined reference to `clGetPlatformIDs'

Error:Execution failed for task ':app:linkArm64-v8aDebugAllHello-jniSharedLibrary'.

A build operation failed. Linker failed while linking libhello-jni.so. See the complete log at: file:///C:/Users/Umut/Desktop/OpenCLTest2/app/build/tmp/linkArm64-v8aDebugAllHello-jniSharedLibrary/output.txt

最佳答案

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

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

解决方案是简单地为您从中获取库的体系结构添加 abiFilter。我从 Galaxy Note 5 获取了该库。我在 gradle 构建中为“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'
}

关于java - Android Studio 中的 OpenCL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36104565/

相关文章:

android - Android SDK Manager 下载器不能恢复支持吗?

Java Jni 和 C++

java - 如何使用 WebSocket 发送定期消息?

android - (jetpack compose) androidx.compose.runtime.internal.ComposableLambdaImpl 无法转换为 kotlin.jvm.functions.Function0

java - Android:显示默认 Activity 而不是启动器

android - 适用于 android、iphone 和 windows phone 的通用编程语言

android - 如何识别基于 x86 的 Android 设备是否可以运行 armeabi-v7a?

Java 获取默认的 UI 颜色

java - Spring SAML : updating Metadata Provider does not update signing certificates used

java - Spring Autowiring "forgot"关于依赖