title: How can "plugins" loaded by libdl refer to symbols in the program which loaded them?
body: <p>Imagine that you have an application with a plugin based architecture, where each plugin is a <code>*.so</code> file that is dynamically loaded with <code>dlopen()</code>.</p>
  
  <p>The main application can refer to symbols via <code>dlsym()</code>, and so it may call functions of the plugin. How can the plugin call functions of the main application?</p>
  
  <p>I know that the main application could provide a struct full of function pointers, which the plugin could use to call into the application. Is there any easier way than that?</p>
  
  <p><strong>Edit:</strong> here's a minimal working example to show what I mean:</p>
  
  <p><code>app.h</code>:</p>
  
  <pre><code>#ifndef APP_H
  #define APP_H
  void app_utility(void);
  #endif
  </code></pre>
  
  <p><code>app.c</code>:</p>
  
  <pre><code>#include &lt;dlfcn.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #include "app.h"
  
  void app_utility(void)
  {
      printf("app_utility()\n");
  }
  
  int main(int argc, char **argv)
  {
      void *handle;
      void (*plugin_function)(void);
      if (argc &lt; 2) {
          fprintf(stderr, "usage: ./app plugin.so\n");
          exit(1);
      }
  
      handle = dlopen(argv[1], RTLD_NOW | RTLD_LOCAL);
      if (!handle) {
          fprintf(stderr, "error loading plugin: %s\n", dlerror());
          exit(1);
      }
  
      plugin_function = dlsym(handle, "doit");
      if (!plugin_function) {
          fprintf(stderr, "error loading symbol: %s\n", dlerror());
          dlclose(handle);
          exit(1);
      }
  
      plugin_function();
  
      dlclose(handle);
      return 0;
  }
  </code></pre>
  
  <p><code>plugin.c</code>:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  #include "app.h"
  
  void doit(void)
  {
      printf("doit()\n");
      app_utility();
      printf("did it!\n");
  }
  </code></pre>
  
  <p>Example usage:</p>
  
  <pre><code>$ gcc -o app app.c -ldl
  $ gcc -shared -o plugin.so
  $ ./app ./plugin.so
  error loading plugin: ./plugin.so: undefined symbol: app_utility
  </code></pre>