#include <stdio.h>

#include <dlfcn.h>
#include <stdlib.h>
#ifndef linux
   #include <link.h> /* redundant on Linux, but not on Illumos */
#endif

const char* libpath = "./animals.so"; /* / in the name is essential.
					 Without it, only standard ld
					 paths will be searched, which
					 don't normally include "." */ 

int main(){
  void *farm_ctx; 
  void (*pig)(), (*cat)(), (*cow)();

  puts("Old MacDonald had a farm...");

  farm_ctx = dlopen(libpath, RTLD_LAZY | RTLD_GLOBAL);
  if (!farm_ctx) {
    fprintf(stderr, "%s\n", dlerror());
    exit(1);
  }

  cat = dlsym( farm_ctx, "cat");
  cow = dlsym( farm_ctx, "cow");
  pig = dlsym( farm_ctx, "pig");

  if( !cat || !cow || !pig ) {
    fprintf(stderr, "%s\n", dlerror());
    exit(1);
  } 


  puts(" and on that farm he had some cats");
  cat();
  puts(" and on that farm he had some pigs");
  pig();
  puts(" and on that farm he had some cows");
  cow();

  return(0);
}