title: Providing symbol of linked shared library to shared library opened with dlopen
body: <p>Consider the following files</p>
  <pre><code># Makefile
  
  all: libdyn.so libmain.so app
  
  libdyn.so: libdyn.cpp
      g++ -fPIC -shared -o libdyn.so libdyn.cpp
  
  libso.so: libso.cpp
      g++ -fPIC -shared -o libso.so libso.cpp
  
  libmain.so: libmain.cpp libso.so
      g++ -Wl,--no-as-needed -fPIC -shared -o libmain.so libmain.cpp -ldl -L`pwd` -lso
  
  app: main.cpp   g++ -o app main.cpp -ldl
      g++ -o app main.cpp -ldl
  </code></pre>
  <pre><code>// libdyn.cpp
  
  #include &lt;iostream&gt;
  
  extern &quot;C&quot; {
  
  extern void foo();
  
  void bar() {
      std::cout &lt;&lt; &quot;Calling foo...&quot; &lt;&lt; std::endl;
      foo();
  }
  
  };
  </code></pre>
  <pre><code>// libso.cpp
  
  #include &lt;iostream&gt;
  
  extern &quot;C&quot; {
  
  void foo() {
      std::cout &lt;&lt; &quot;Hello from foo&quot; &lt;&lt; std::endl;
  }
  
  };
  </code></pre>
  <pre><code>// libmain.cpp
  
  #include &lt;iostream&gt;
  #include &lt;dlfcn.h&gt;
  
  int main_fun() {
      void* handle = dlopen(&quot;./libdyn.so&quot;, RTLD_LAZY);
      void (*bar_ptr)() = reinterpret_cast&lt;void(*)()&gt;(dlsym(handle, &quot;bar&quot;));
      std::cout &lt;&lt; &quot;Calling bar...&quot; &lt;&lt; std::endl;
      (*bar_ptr)();
      return 0;
  }
  </code></pre>
  <pre><code>// main.cpp
  
  #include &lt;iostream&gt;
  #include &lt;dlfcn.h&gt;
  
  int main() {
      void* handle = dlopen(&quot;./libmain.so&quot;, RTLD_LAZY);
      int (*main_fun_ptr)() = reinterpret_cast&lt;int(*)()&gt;(dlsym(handle, &quot;_Z8main_funv&quot;));
      std::cout &lt;&lt; &quot;Calling main_fun...&quot; &lt;&lt; std::endl;
      (*main_fun_ptr)(); 
  }
  </code></pre>
  <p>Calling <code>./app</code> yields</p>
  <pre><code>Calling main_fun...
  Calling bar...
  Calling foo...
  ./app: symbol lookup error: ./libdyn.so: undefined symbol: foo
  </code></pre>
  <p>and <code>ldd libmain.so</code> yields</p>
  <pre><code>    linux-vdso.so.1 (0x00007ffd903f8000)
      libdl.so.2 =&gt; /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe05cdb8000)
      libso.so (0x00007fe05cdb3000)
      libstdc++.so.6 =&gt; /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe05cb99000)
      libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe05ca4a000)
      libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe05ca2f000)
      libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe05c83b000)
      /lib64/ld-linux-x86-64.so.2 (0x00007fe05cddf000)
  </code></pre>
  <p>I don't understand why <code>libdyn</code> doesn't have access to <code>foo</code>. <code>libmain</code> links against <code>libso</code>, which provides <code>foo</code> and <code>libdyn</code> is loaded by <code>libmain</code>, so shouldn't <code>foo</code> then be found?</p>
  <p>I am interested in solving this problem, however, there are a few constraints. As could be suspected, this is kind of a MWE for my real problem. In my application <code>libmain.so</code> is called using the Java Native Interface. Furthermore, only <code>libmain</code> is user code. <code>libso</code> and <code>libdyn</code> are external libraries that would be very difficult for me to recompile, but it would be doable. Lastly, there isn't a single <code>foo</code> function, but thousands and also global variables that must be shared in the way <code>foo</code> should be shared.</p>