title: dlopen, factory pattern and the virtual method table
body: <p>I'm trying to wrap my head around how the factory pattern works internally when using dlopen in c++. Sorry for long post. </p>
  
  <p>tl;dr; Question is in <strong>Bold</strong> below.</p>
  
  <p>Snippets from <a href="http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html" rel="nofollow noreferrer">http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html</a> with error checking removed to save space:</p>
  
  <p>main.cpp</p>
  
  <pre><code>#include "polygon.hpp"
  #include &lt;iostream&gt;
  #include &lt;dlfcn.h&gt;
  
  int main()
  {
      using std::cout;
  
      // load the triangle library
      void* triangle = dlopen("./triangle.so", RTLD_LAZY);
  
      // load the symbols
      // create function pointers
      // (Exposed with extern "C")
      polygon* create_triangle = (polygon*) dlsym(triangle, "create"); 
      void* destroy_triangle = (void*) dlsym(triangle, "destroy");
  
      // create an instance of the class
      polygon* poly = create_triangle();
  
      // use the class
      poly-&gt;set_side_length(7);
      cout &lt;&lt; "The area is: " &lt;&lt; poly-&gt;area() &lt;&lt; '\n';
  
      destroy_triangle(poly); // destroy the class
  
      dlclose(triangle);     // unload the triangle library
  </code></pre>
  
  <p>}</p>
  
  <p>polygon.hpp</p>
  
  <pre><code>#ifndef POLYGON_HPP
  #define POLYGON_HPP
  
  class polygon
  {
  protected:
      double side_length_;
  
  public:
      polygon()
          : side_length_(0) {}
  
      virtual ~polygon() {}
  
      void set_side_length(double side_length)
      {
          side_length_ = side_length;
      }
  
      virtual double area() const = 0;
  };
  
  // the types of the class factories
  typedef polygon* create_t();
  typedef void destroy_t(polygon*);
  
  #endif
  </code></pre>
  
  <p>triangle.hpp</p>
  
  <pre><code>#include "polygon.hpp"
  #include &lt;cmath&gt;
  
  class triangle : public polygon
  {
  public:
      virtual double area() const
      {
          return side_length_ * side_length_ * sqrt(3) / 2;
      }
  };
  
  
  // the class factories
  
  extern "C" polygon* create()
  {
      return new triangle;
  }
  
  extern "C" void destroy(polygon* p)
  {
      delete p;
  }
  </code></pre>
  
  <p>So looking at the main() function what I see is this.</p>
  
  <ol>
  <li>dlopen creates a handle.</li>
  <li>Function pointers created so that the triangle class can create a new triangle object and destroy it. (dlopen is giving us a memory location to branch to.)</li>
  <li>create_triangle() returns a triangle casted into a polygon (since we know the methods of the polygon.</li>
  <li>We set the internal member side_length_ using the base class's set_side_length method.</li>
  </ol>
  
  <p><strong>Here is the question:</strong></p>
  
  <p><strong>When poly->area() is called how is this found in the triangle object?</strong></p>
  
  <ul>
  <li>We know where in memory the base class has it's "virtual area()" method.</li>
  <li>Since "triangle.so" is dynamically loaded, the compiler isn't able to say on I recognize that the triangle area() is overriding the polygon area() in your program.</li>
  <li>The names are completely mangled at this point and the .so could have been compiled with clang++ and the program could have been compiled with g++. So potentially having no hope of recognizing them at this point.</li>
  </ul>
  
  <p>Does the Virtual Member Table keep the virtual methods in order according to when they appear? So would this code break it?</p>
  
  <p>polygon.hpp</p>
  
  <pre><code>...
  virtual double area() const = 0;
  virtual double parameter() const = 0;
  ...
  </code></pre>
  
  <p>triangle.hpp</p>
  
  <pre><code>...
  double parameter() const { ... } // implementing and defining parameter first
  area() const { ... } // implementing and defining second.
  ...
  </code></pre>
  
  <p>I know you would want to keep them in order... but let's say we subclass a couple more times and they get defined in a different order...</p>
  
  <p>Any help on this would be great. I just can't visualize what is going on in the memory here to make this actually work.</p>
  
  <p>Thanks! And sorry for the long post.</p>