C++ – dynamic_cast fails when hiding symbols

dynamic_cast fails when hiding symbols… here is a solution to the problem.

dynamic_cast fails when hiding symbols

I have a lot of static libraries. One is static_lib_a.a. I created a dynamic library dynamic_lib.so to put them together.

static_lib_a.a use xerces 3.1.1 parse XML. Below is a code snippet from static_lib_a.a

xerces::DOMElement *pElementNode = dynamic_cast<xerces::DOMElement *>(pNode);

The type of pNode is xerces::D OMNode. It is assigned to xerces::D an object of OMElement. This line of code will be transformed downward.

To hide all symbols of static_lib_a.a in dynamic_lib.so, I built this static library using -fvisibility=hidden. I found that if I add –fvisibility=hidden, pElementNode will return a NULL pointer at runtime.

The gcc compiler version is 3.4.4.

Has anyone ever encountered a similar issue?

Solution

The root cause of the problem is described in the gcc wiki, under the section titled “C++ Exception Problem”. Make sure you follow the “Fuzzy Links” link there and read the section on virtual tables and type information.

This all applies to your case, because the classes xerces::D

OMNode and xerces::D OMElement do not contain non-pure, non-inline virtual functions (in fact, these classes are completely included in the title). This means that the virtual table of each class is emitted in each target file that contains its header.

Type info symbols of any class required for dynamic_cast to function properly are emitted in the same object as the virtual table, that is, in each target file that contains its header.

When you mark a library as hidden visibility, all type info symbols xerces::D OMNode and xerces::D OMElement in objects from static_lib_a.a are marked as hidden. As the wiki page points out, this ensures that the linker then marks it as hidden in dynamic_lib.so and that your dynamic_cast will fail.

Related Problems and Solutions