当前位置: 移动技术网 > IT编程>开发语言>C/C++ > 在Android平台使用SNPE应链接libc++库

在Android平台使用SNPE应链接libc++库

2020年03月18日  | 移动技术网IT编程  | 我要评论

党的最高纲领是什么,游易德,中国钓鱼视频

在android平台使用snpe库以前都什么太大问题,最近因为要使用userbuffer,编译时报链接错误:

undefined reference to `zdl::dlsystem::tensorshape::tensorshape(std::vector<unsigned long, std::allocator<unsigned long> >)

因为是链接错误,而且查看了头文件,tensorshape有对应的重载构造函数,所以怀疑snpe的库文件libsnpe.so不对。怀疑高通提供的库文件不对,好像这也不太可能,一时间陷入了困境。

开始从高通的客服那边没有得到太有用的信息,只能自己想办法。用objdump从库文件dump出符号表看看有没有对应的函数。但是高通release库肯定是把符号表去掉了的,只能通过objdump -t出来动态符号。从动态符号中筛选出和tensorshape相关的,然后找一些看着可能像的符号,用c++filt还原出函数名。

先在x86_64平台的libsnpe.so找到了

c++filt _zn3zdl8dlsystem11tensorshapec1est6vectorimsaimee
zdl::dlsystem::tensorshape::tensorshape(std::vector<unsigned long, std::allocator<unsigned long> >)

这和我们需要的函数是一样的,也就是说x86_64平台的libsnpe.so肯定是包含这个重载的函数实现的。那android平台的不应该没有啊?继续在android平台的libsnpe.so里找,终于找到

c++filt _zn3zdl8dlsystem11tensorshapec2enst6__ndk16vectorimns2_9allocatorimeeee
zdl::dlsystem::tensorshape::tensorshape(std::__ndk1::vector<unsigned long, std::__ndk1::allocator<unsigned long> >)

看着像,但是和平常见到的是不太一样,vector的定义是std::__ndk1::vector。这说明snpe链接的是llvm的标准libc++库。这样原因清楚了。我们编译使用的是cmake,最开始在build.gradle文件中并没有指定android_stl变量,编译使用的应该不是libc++库,导致了链接错误。(按照ndk文档的说法,android_stl默认的是c++_static,这是libc++的静态库。按理是能够链接通过的,实际也试过了,android_stl指定c++_static是能够编译通过的。但是不指定,就会出现上面的undefined reference错误。我怀疑默认使用的是gnu的库)

因为还使用了opencv的库(用的是opencv3的版本),如果改用libc++,会出现链接opencv出错。查找opencv的文档,opencv4.0.0开始使用c++11库,因此改用opencv4。在build.gradle文件中加上android_stl定义,编译通过。

android {
    defaultconfig {
        externalnativebuild {
            cmake {
                arguments '-dandroid_stl=c++_shared'
            }
        }
    }
}

按ndk的文档,从ndk r18开始,libc++成为ndk中唯一可用的stl。因为我们使用的ndk版本还比较低,所以开始并没有出错。随着ndk升级,不仅r18开始libc++是唯一的stl,而且gcc也不再支持,只能使用clang。还是慢慢转过去了,以免出现一些莫名其妙的问题。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网