dynamic_cast 在 clang 上无法跨模块边界工作
dynamic_cast doesn't work across module boundaries on clang
我看到一个非常奇怪的故障,与中描述的问题非常相似llvm clang编译器上的dynamic_cast失败:对于派生类型的对象,当我试图从基类型向下转换为派生类型时,dynamic_cast
返回nullptr
。在我的例子中,虽然typeid
实际上显示了相同的动态类型。
下面是我用来验证运行时类型的调试函数。它获取一个SrcType*
的指针,并尝试将其动态地转换为DstType*
的指针。如果转换失败,即返回的指针为nullptr
,则会打印一条错误消息。VERIFY()
宏检查条件是否为真:
template<typename DstType, typename SrcType>
void CheckDynamicType( SrcType *pSrcPtr )
{
VERIFY(dynamic_cast<DstType*> (pSrcPtr) != nullptr,
"Dynamic type cast failed. Src typeid: '", typeid(*pSrcPtr).name(),
"' Dst typeid: '", typeid(DstType).name(), ''');
}
这是我得到的输出:
Dynamic type cast failed. Src typeid: 'N8Diligent15RefCountersImplE' Dst typeid: 'N8Diligent15RefCountersImplE'
我使用的是安卓ndk r16工具链中的clang编译器。我正在用rtti旗编译。同样的代码在gcc和msvc上运行良好。另一点信息是:如果我使用gnustl
运行时构建代码,代码也可以正常工作(我不确定gnu-stl如何使用clang,但无论如何)。
更新
在花了几个小时研究这个问题后,我发现dynamic_cast
在另一个模块中创建的对象上使用时会失败。由此使用clang++、-fvisibility=hidden、typeinfo和类型擦除,如果类标记为__attribute__((visibility("default")))
,那么dynamic_cast
应该可以工作,这样来自两个模块的typeid
结构就会合并。然而,这也于事无补,我仍然看到这个问题。
如果您使用的是股票系统编译器,那么编译器的dynamic_cast不起作用的可能性几乎为零。这是测试和广泛使用的一切,从系统软件。
相关文章:
- 尝试导入pybind-opencv模块时出现libgtk错误
- std::当在256字节边界上写入整数时,流的奇怪行为
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 内联如何影响模块接口中的成员函数
- C++返回 Numpy 数组的 Python 扩展模块
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 使用不变量来确定二分搜索中的边界条件
- 如何从线程中的不同模块调用函数?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 如何使用 soong 命名空间来有条件地编译模块
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 在 64 位边界上对齐C++结构数组?
- CMake - 模块 + 库混淆
- 特征 LLT 模块给出不正确的结果?
- 枚举进程模块在有效句柄上返回无效句柄
- 清理跨越Windows DLL模块边界的堆分配资源时出现问题
- dynamic_cast 在 clang 上无法跨模块边界工作
- 为API使用std::函数(跨越模块边界)
- Itanium和MSVC abi中跨模块边界的RTTI