我有很多静态库.一个是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异常问题”一节中进行了描述.确保您单击那里的“模糊链接”链接,并阅读了有关虚拟表和typeinfo的部分.
这一切都适用于您的情况,因为xerces :: DOMNode和xerces :: DOMElement类不包含任何非纯的,非内联的虚函数(实际上,这些类完全包含在头文件中).这意味着任何一个类的虚拟表都会在包含其标题的每个目标文件中发出.
dynamic_cast正常工作所需的任一类的typeinfo符号,都在与虚拟表相同的对象中发出,即,在包含其头的每个对象文件中发出.
当您用隐藏的可见性标记您的库时,来自static_lib_a.a的对象中xerces :: DOMNode和xerces :: DOMElement的所有typeinfo符号都标记为隐藏.正如Wiki页面所指出的那样,这可确保链接器随后将其标记为在dynamic_lib.so中隐藏,并且您的dynamic_cast将失败.