小言_互联网的博客

Android studio 使用opencl库(realme 手机)

1017人阅读  评论(0)

唉,尝试了很多天之后,经历各种各样报错,查找好几天,解决五分钟,终于可以在Android Studio上使用opencl!!!!

一、查看自己手机支不支持opencl,下载opencl-z软件

链接:https://pan.baidu.com/s/16irhsWaBLGXjy96zPCa7MQ

提取码:1233

二、开始操作

       一、先下载platform-tools,这样子就可以使用adb命令了。

       二、adb shell 命令进入手机(手机已经连接,并且处于usb调试模式)

       三、进入 cd /system/vendor/lib 看看有没有 libopencl.lib

       四、把opencl.so文件拉到电脑来(随意一个地方),放到指定目录(android studio)

adb pull /system/vendor/lib/libOpenCL.so d:/opencl

        五、编译,运行

                1.cmakelist.txt添加库文件


  
  1. add_library(
  2.         OpenCL
  3.         SHARED
  4.         IMPORTED)
  5. set_target_properties(OpenCL PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jinLibs/${ANDROID_ABI}/libOpenCL.so)
  6. target_link_libraries(
  7.         myopencldemo
  8.         OpenCL
  9.         ${log-lib})

                2.app下的build.gradle添加内容


  
  1. externalNativeBuild {
  2.    cmake {
  3.         abiFilters 'arm64-v8a'
  4.     }
  5. }
  6. ndk{
  7.      abiFilters 'arm64-v8a' // 指定编译
  8.  }

不指定编译的话,貌似会出现错误error adding symbols: File in wrong format clang++.exe: error: linker command failed with exit code 1

                3. 在native-lib.cpp中使用OpenCL


  
  1. //添加头文件
  2. #include <android/log.h>
  3. #include <android/native_window_jni.h>
  4. #include <CL/cl.h>
  5. #include <CL/cl_platform.h>
  6. #define LOGD(...) __android_log_print(ANDROID_LOG_INFO,"David",__VA_ARGS__)
  7.   //添加代码
  8.     cl_platform_id *platforms; //查询后获得的平台列表,存放所有平台的ID
  9.     cl_uint num_platforms; //当前可查询的平台的数量
  10.     jint buffer; //创建一个buffer用以缓存平台数量,并传递;
  11.     clGetPlatformIDs( 0, NULL, &num_platforms);
  12.     //当第二个参数为NULL时,函数将会查询当前可用平台的数量,并保存在第三个参数;
  13.     platforms = new cl_platform_id[num_platforms]; //查询后获得的平台列表,存放所有平台的ID
  14.     clGetPlatformIDs(num_platforms ,platforms , NULL);
  15.     //获取平台数量后可以查询平台,将查询到的平台ID保存在第二个列表参数中
  16.     buffer = num_platforms;
  17.     LOGD( "平台数:%d\n",buffer);
  18.     LOGD( "平台ID:%d\n",platforms);
  19. LOGD( "=============================================\n");

               4.那肯定是错误了。。。。,缺少库文件

          引入,又发现再缺少库文件。。。。

               所以说,还是看下缺少啥文件把。。。。。linux系统下,objdump命令查看

objdump -x libOpenCL.so | grep NEEDED

终于找全了,开心,应该这次稳了!!!!!

(根据手机不同,可能需要库会不一样)

        六、错误排查

       1、Fatal signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xc5614e64 in tid 22126

       一个错误,一杯水,半天过去。这个问题据说是是因为这几种情况。

第一空指针问题;第二函数有返回值,但是结束了没有返回。

但,我没有解决,也没有这问题,那么简单的程序,是不是。。。

        2、一顿操作,看logcat(terminal窗口 adb logcat | findstr “程序名”),发现有这几个问题。

Access denied finding property "ro.odm.prev.product.name"

/Zygote: Unable to open libbeluga.so: dlopen failed: library "libbeluga.so"

以为是权限问题,开始给手机刷root权限,又是一晚上过去,好在解决了,刷成功,不懂,可看

Realme x 刷有root权限_czhunian的博客-CSDN博客

        3、刷完之后,觉得又行了,一编译运行,好吧,又出现问题。。。。

       UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_Unwind_Resume"

  找到一个命令readelf -sW libnative-lib.so| grep _Unwind
  The UND in the Ndx column means Undefined symbol
  参考链接:https://github.com/google/oboe/issues/966        然后呢???又是半天过去,唉

        七、最后放弃,那是不可能的,重新新建一个项目,从头开始

新问题来了:A/libc: Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xe1f7fb

虽然跟上面第一个问题不是很像,但是找了一圈,好像导致原因都是一样,就是空指针异常,没有返回值啥的,又是没有解决的问题。。。,但是又学到一个新知识

addr2line -f -e libnative-lib.so 0xe1f7fb90,查看到底是哪个函数出现!!!

-e 输出错误代码行数和文件路径 -f 输出函数名

addr2line在ndk下

       

 但是问题又来了,输出是 ???,好吧,绝望了。。。

搜起来,找到一个不错的解决方案,可以看看

addr2line 输出为?:0可能原因_qq_23101811的博客-CSDN博客_add2line显示???

但是死活搞不定,太菜了。。。。

说是要编译成debug的,cmakelist.txt 添加命令,add_definitions("-Wall -g")

但是还是不行,所以说摆烂了,不搞了,累了。。。

        八、又来了,重新新建项目,换个手机

               发现,运行成功了,wc,喜大普奔,一看平台数0,md,为什么。。。。

        1.先看看为什么之前的不行,现在的项目编译运行,直接通过了,一对比,发现

          

 这边不能引入动态库,咦,为什么啊,明明动态库要加载进行,不然怎么找得到!wc,后面想一想可能是因为手机有默认的执行环境,她自己去里面找了找了,之前的用了自己加载的反而会出错。

        2.一看,clGetPlatformIDs函数 返回CL_INVALID_VALUE(-30)

开始各种操作了,报错是 参数不合法,可是简单啊,咋那么可能不合法。。。

郁闷一晚上

        3.算是长征结束了,真的喜大普奔!!!!

换个操作搜,问Android studio 使用opencl,发现了问题,唉

在Android Studio上使用OpenCL_gaussrieman123的博客-CSDN博客_opencl 安卓

说是,因为google是不公开支持opencl的,所以NDK中并不会有libOpenCL.so,这个库都是放在各个厂家的库中,比较常见的位置是"system/vendor/lib/libOpenCL.so",把所需的动态库全部pull出来,看成app的私有库来加载,可以解决编译的问题,但是在使用clGetPlatforms时,会找不到可用的platform;使用stub,将libOpenCL.so动态加载,libopencl.c完成适配平台和封装接口的工作,主要用到dlopendlsym,前者用来加载vendor支持的CL动态库,后者用来映射接口;这边直接将stub编译成一个静态库使用即可。

历时快一周的简单的opencldemo,终于可以运行成功。算是对得起这几天了,唉。

代码:GitHub - czhunian/opencldemo at master


转载:https://blog.csdn.net/qq_38295645/article/details/127602666
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场