更换c++_shared运行时库后,Android 5及以下机型执行dynamic_pointer_cast返回nullptr的问题

   项目原本使用gnustl_shared作为ndk的C++运行时库,没有该问题。考虑官方将会在NDK r18版本移除gnustl,于是项目将C++运行时库切换到c++_shared,在Android 5及以下机型测试过程中,发现dynamic_pointer_cast始终返回nullptr的问题。

    原因分析:用于dynamic_pointer_cast转化的类对象定义、创建和使用是在不同的so库中进行的,这个通过readelf -sW xxx.so|grep "yyy"(Android NDK里面也有改程序,ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin>arm-linux-androideabi-readelf.exe -sW xxx.so|findstr "yyy")可以看到该符号是WEAK DEFAULT,这样就无法正常在libc++里面动态转型,而gnustl对改符号的判断较宽松,判断符号字符串相等即可转化,libc++则还需要判断符号地址。

    解决方案:参考ndk官方issue,通过给跨库定义的类增加非内联非纯虚的虚函数(key function)实现(特别注意要实现在cpp文件,因头文件会被编译器优化成内联函数),这时再用readelf可以看到符号变成了GLOBAL DEFAULT,这时便可以正常跨库使用dynamic_pointer_cast转化

 

参考:

https://github.com/android-ndk/ndk/issues/519 about dynamic_pointer_cast fail

https://github.com/android-ndk/ndk/issues/533  about dynamic_pointer_cast fail

http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable  libc++ ABI key function

https://codeday.me/bug/20180215/131966.html elf符号列含义

https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md#rtti_exceptions-not-working-across-library-boundaries 谷歌ndk官方解释

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值