动态强制转换(dynamic_cast)在OSx(XCode)上使用.dylib失败

时间:2018-03-16 09:07:08

标签: c++ c++11 clang

我正在构建一个由主要目标和几个插件组成的应用程序(在OSx案例中为dylib' s)。我开始在这个项目中使用std::dynamic_pointer_cast来强制转换并测试我的类层次结构中的特定类型。一般来说,这种方法效果很好,而且对于我的应用程序来说还要快得多。

我现在的问题是,有时dynamic_castdynamic_pointer_cast会在从插件中提取的代码段中失败。我将dlopenRTLD_GLOBAL | RTLD_LAZY一起使用,并且我还使用--export_dynamic链接器标记编译我的主目标,以确保所有符号都被拉入。但是,仍然一些动态演员表演失败了。

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

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

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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