c++ - OSx (XCode) 上的 .dylib 动态转换 (dynamic_cast) 失败

标签 c++ c++11 clang

我正在构建一个由一个主要目标和几个插件(dylib 在 OSx 案例中)组成的应用程序。我开始在这个项目上使用 std::dynamic_pointer_cast 来转换和测试我的类层次结构中的特定类型。总的来说,这很好用,并且对于我的应用程序来说已经足够快了。

我现在的问题是,有时 dynamic_castdynamic_pointer_cast 会在从插件中提取的代码段中失败。我正在使用 dlopenRTLD_GLOBAL | RTLD_LAZY 并且我还在使用 --export_dynamic 链接器标志编译我的主要目标,以确保所有符号都被拉入。但是,仍然有一些动态转换在它们不应该失败的时候失败了。

我正在测试的类是多态的(虚拟析构函数)并且 typeid(...).name() 总是返回一致的结果。然而,在某些情况下,动态转换会返回 null,即使 typeid 信息看起来是正确的。

当我为调试编译时,转换似乎总是成功(没有优化)。

我应该在插件或目标上使用 OSx(XCode、clang)的其他哪些链接器标志,以确保动态转换在我的情况下正常工作?

最佳答案

当您的应用程序还使用动态库 (.dylib) 时,我终于找到了链接器设置以确保 dynamic_cast 在 OSx 上正常工作。

我的问题:我与多个 dylib 共享了一个库中的一些代码,然后使用动态转换来检查并从一种类型转换为另一种类型。然后在某些情况下(在 Release 下编译时)dynamic_cast(s) 会失败,即使 typeid(..).name() 确认我正在使用正确的类型。

我尝试使用 dlopen(.., RTLD_GLOBAL) 加载我的插件,这应该允许动态库中定义的符号进行全局解析,并且也可用于其他插件。这并没有解决我的问题,尽管我确实将它保留在代码中,因为拥有它是有意义的。

我尝试将 -export_dynamic 链接器标志添加到我的应用程序,这应该确保在使用 dlopen 加载时所有全局符号都与动态库共享。这同样没有解决我的问题。

解决方法: 我终于遇到了一个引用,它说 Apple/BSD 对动态库使用两级符号名称解析,其中库本身被记录为符号解析的一部分。这可以通过 -flat_namespace 链接器标志关闭。在我为所有插件添加此标志后,一切正常。

使用 -flat_namespace 链接器标志,我所有的 dynamic_casts 都按预期工作。

关于c++ - OSx (XCode) 上的 .dylib 动态转换 (dynamic_cast) 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49316779/

相关文章:

c++ - 错误 : Implicit instantiation of "Class" within its own definition. c++11

c++ - 是否可以在 C++14 中创建具有可选模板参数的类型元组?

c++ - 原子/非原子混合,有任何保证吗?

c++ - 启用 -std=c++0x 时自定义分配器的编译问题

c++ - Visual Studio 11(测试版)中的强类型枚举类

ruby - sudo gem install jekyll -- 失败 -- clang 错误未知参数

c - Mac OS X 塞拉利昂 : Undefined symbols for architecture x86_64

ios - Clang 中所有 Objective-C 预处理器指令的列表

c++ - 用 vector 计算元素出现的次数

c++ - 在 C++ 中,如何在 X 秒后重置类中的变量?