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

Dynamic cast (dynamic_cast) fails with .dylib on OSx (XCode)

本文关键字:XCode dylib 失败 OSx 转换 dynamic 动态 cast      更新时间:2023-10-16

我正在构建一个由一个主目标和几个插件组成的应用程序(在OSx的情况下是dylib)。 我开始在此项目中使用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 下编译时),即使typeid(..).name()确认我正在使用正确的类型,dynamic_cast也会失败。

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

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

溶液: 我终于遇到了一个参考资料,说 Apple/BSD 对动态库使用两级符号名称解析,其中库本身记录为符号解析的一部分。可以使用-flat_namespace链接器标志将其关闭。 在我为所有插件包含此标志后,一切正常。

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