c++ - 隐藏符号时 dynamic_cast 失败

标签 c++ linux gcc xerces gcc3

我有很多静态库。一个是 static_lib_a.a。我创建了一个动态库 dynamic_lib.so 来将它们放在一起。

static_lib_a.a中使用xerces 3.1.1解析xml。以下是static_lib_a.a

中的代码片段
xerces::DOMElement *pElementNode = dynamic_cast<xerces::DOMElement *>(pNode);

pNode 的类型是 xerces::DOMNode。它被分配给 xerces::DOMElement 的一个对象。这行代码将进行向下转型。

为了在dynamic_lib.so中隐藏static_lib_a.a的所有符号,我使用-fvisibility=hidden来构建这个静态库。我发现如果我添加 -fvisibility=hidden,pElementNode 将在运行时返回 NULL 指针。

gcc编译器版本为3.4.4。

有没有人遇到过类似的问题?

最佳答案

问题的根源在 gcc wiki 中进行了描述在标题为“C++ 异常问题”的部分下。确保您遵循那里的“模糊链接”链接并阅读有关虚拟表和类型信息的部分。

这一切都适用于您的情况,因为类 xerces::DOMNodexerces::DOMElement 不包含非纯的、非内联的虚函数(实际上这些类完全包含在标题中)。这意味着每个类的虚拟表都会在包含其 header 的每个目标文件中发出。

dynamic_cast 正常工作所需的任一类的类型信息符号在与虚拟表相同的对象中发出,即在包含其标题的每个目标文件中发出。

当您将库标记为隐藏可见性时,来自 static_lib_a.a 的对象中 xerces::DOMNodexerces::DOMElement 的所有类型信息符号都被标记为隐藏。正如 wiki 页面指出的那样,这确保链接器随后将其标记为隐藏在 dynamic_lib.so 中,并且您的 dynamic_cast 将失败。

关于c++ - 隐藏符号时 dynamic_cast 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5116333/

相关文章:

c++ - 符号转换发生在哪里?

缺少 Python.h header

c++ - 如何在ChaiScript 中注册重载的模板成员函数?

C++:动态创建以for循环迭代器命名的数组

c++ - 什么时候使用虚拟析构函数?

windows - Windows 与 Linux/UNIX 中 Perl 的 waitpid() 和 IPC::Open2

python - 尝试在虚拟环境中安装 flask 时出错

c++ - 在类头中包含 typedef

c - Linux:用负 pid 杀死

c++ - 为什么为一个什么都不返回的函数声明一个返回值只会导致 gcc8 中的运行时崩溃