唉,尝试了很多天之后,经历各种各样报错,查找好几天,解决五分钟,终于可以在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添加库文件
-
add_library(
-
-
OpenCL
-
-
SHARED
-
-
IMPORTED)
-
-
set_target_properties(OpenCL PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jinLibs/${ANDROID_ABI}/libOpenCL.so)
-
-
-
-
target_link_libraries(
-
-
myopencldemo
-
-
OpenCL
-
-
${log-lib})
2.app下的build.gradle添加内容
-
externalNativeBuild {
-
-
cmake {
-
-
abiFilters
'arm64-v8a'
-
-
}
-
-
}
-
-
ndk{
-
-
abiFilters
'arm64-v8a'
// 指定编译
-
-
}
不指定编译的话,貌似会出现错误error adding symbols: File in wrong format clang++.exe: error: linker command failed with exit code 1
3. 在native-lib.cpp中使用OpenCL
-
//添加头文件
-
-
#include <android/log.h>
-
-
#include <android/native_window_jni.h>
-
-
#include <CL/cl.h>
-
-
#include <CL/cl_platform.h>
-
-
#define LOGD(...) __android_log_print(ANDROID_LOG_INFO,"David",__VA_ARGS__)
-
-
//添加代码
-
-
cl_platform_id *platforms;
//查询后获得的平台列表,存放所有平台的ID
-
-
cl_uint num_platforms;
//当前可查询的平台的数量
-
-
-
-
jint buffer;
//创建一个buffer用以缓存平台数量,并传递;
-
-
clGetPlatformIDs(
0,
NULL, &num_platforms);
-
-
//当第二个参数为NULL时,函数将会查询当前可用平台的数量,并保存在第三个参数;
-
-
platforms =
new cl_platform_id[num_platforms];
//查询后获得的平台列表,存放所有平台的ID
-
-
clGetPlatformIDs(num_platforms ,platforms ,
NULL);
-
-
//获取平台数量后可以查询平台,将查询到的平台ID保存在第二个列表参数中
-
-
buffer = num_platforms;
-
-
LOGD(
"平台数:%d\n",buffer);
-
-
LOGD(
"平台ID:%d\n",platforms);
-
-
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完成适配平台和封装接口的工作,主要用到dlopen和dlsym,前者用来加载vendor支持的CL动态库,后者用来映射接口;这边直接将stub编译成一个静态库使用即可。
历时快一周的简单的opencldemo,终于可以运行成功。算是对得起这几天了,唉。
代码:GitHub - czhunian/opencldemo at master
转载:https://blog.csdn.net/qq_38295645/article/details/127602666