title: Loading classes - dynamical link library returned undefined symbol error
body: <p>I'm using C++ dlopen() to link a shared library named as lib*.so (in directory A) in my main program (in directory B).</p>
  
  <p>I experimented on some simple function loading. Every thing works very well. However, it gave me a headache when I was trying to load class and factory functions that return a pointer to the class object. (I'm using the terms from the tutorial below)</p>
  
  <p>The methodology I used was based on the examples in chapter 3.3 of this tutorial <a href="https://www.tldp.org/HOWTO/C++-dlopen/thesolution.html#externC" rel="nofollow noreferrer">https://www.tldp.org/HOWTO/C++-dlopen/thesolution.html#externC</a>.</p>
  
  <p>There is a bit of polymorphism here ... lib*.so contains a child class that inherits a parent abstract class from the main program directory (directory B). When dlopen() tries to load lib*.so in the main program, it failed due to "undefined symbol". </p>
  
  <p>I used nm command to examine the symbol tables in lib*.so and main program binary. The symbols in these binaries are: </p>
  
  <p>lib*.so : U _ZTI7ParentBox<br>
  main program binary: V _ZTI7ParentBox</p>
  
  <p>ParentBox is the name of the parent class inherited by ChildBox in lib*.so. Note that parent class header file is in another project in directory B. </p>
  
  <p>Although there is name mangling the symbol names are exactly the same. 
  I'm just wondering why the dynamic linker cannot link them? and giving me undefeind symbol error for dlopen()?</p>
  
  <p>Am I missing the understanding of some key concepts here? </p>
  
  <p>P.S. more strangely, it was able to resolve the symbols for member functions between the child class (U type symbol) in lib*.so (T type symbol) and parent class. Why is it able to do this but not able to resolve the undefined symbol for parent class name?</p>
  
  <p>(I've been searching around for a long time and tried -rdynamic, -ldl stuff though I'm not fully understood what they are, but nothing worked)</p>
  
  <p><strong><em>Update 04 April 2019:</em></strong> 
  This is the g++ command line I used to make the main program binary.  </p>
  
  <pre><code>g++ -fvisibility=hidden -pthread -static-libgcc -static-libstdc++ \
  -m64 -fpic -ggdb3 -fno-var-tracking-assignments -std=c++14 \
  -rdynamic \
  -o ./build/main-prog \
  /some_absolute_path/ParentBox.o \
  /some_other_pathen/Triangle.o \
  /some_other_pathen/Circle.o \
  /some_other_pathen/&lt;lots_of_depending_obj&gt; \
  /some_absolute_path/librandom.a \
  -lz -ldl -lrt -lbz2
  </code></pre>
  
  <p>I searched every argument of this command line in <a href="https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html" rel="nofollow noreferrer">https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html</a> (This seems to be a good reference site for all fellow programmers working with large projects with complicated g++ line :) )</p>
  
  <p>Thanks to @<a href="https://stackoverflow.com/users/50617/employed-russian">Employed Russian</a>. With his instructions, the problem narrows down to export the symbols in main program binary. </p>
  
  <p>However, the main program binary has lots of dependencies as you can see from the above command, Circle, Triangle and lots of other object files. 
  We also need to add "-rdynamic" to the compilation of Circle, Triangle and other dependency object files. Otherwise it does not work. </p>
  
  <p>In my case, I added "-rdynamic" to all files in my project to export all symbols. Not sure about "-fvisibility=hidden" doing anything good. I removed all of them in my Makefile anyway... I know this is not the best way but I will worry about speed later when everything is functionally correct. :)</p>
  
  <p><strong>More Updates:</strong>
  The correct solution is in @Employed Russian's update in the answer. 
  My previous solution happened to work because I also removed "-fvisibility=hidden". It is not necessary (and probably wrong) to add -rdynamic to all objects used in the final link. 
  Please refer to @Employed Russian's explanation which addresses the core issue. </p>
  
  <p><strong>Final Update:</strong> 
  For fellow programmers who are interested in how C/C++ program is executed and how library can be linked, here is a good reference web course (Life of Binary) by Xeno Kovah: <a href="http://opensecuritytraining.info/LifeOfBinaries.html" rel="nofollow noreferrer">http://opensecuritytraining.info/LifeOfBinaries.html</a></p>
  
  <p>You can also find a playlist on youtube. Just search "Life of Binary"</p>