main.c:

#include <stdio.h>  /* printf         */
#include <string.h> /* strcat, strcpy */
#include <dlfcn.h>  /* dl stuff       */
#include <stdint.h> /* intptr_t       */

/* conveniences for casting */
typedef void (*PRINTME)(const char *);
typedef int (*ADD)(int, int);

int main(void)
{
  const char *soname = "hello";   /* base name of a .dll or .so */
  const char *fname1 = "printme"; /* function to call (text)    */
  const char *fname2 = "add";     /* function to call (text)    */

  PRINTME printme; /* void printme(const char *) */
  ADD add;         /* int add(int, int)          */
  void *lib;       /* library handle            */
  char *error;     /* dl functions may fail     */
  int result;      /* result of the addition    */

  char buffer[100]; /* used to build the filename */

    /* decorate the filename: hello ==> ./libhello.so */
  strcpy(buffer, "./lib");
  strcat(buffer, soname);
  strcat(buffer, ".so");

    /* load the shared library */
  lib = dlopen(buffer, RTLD_LAZY);
  error = dlerror();
  if (error)
  {
    printf("Error: %s\n", error);
    return 1;
  }

    /* get add funtion and call it */
  add = (ADD)(intptr_t)dlsym(lib, fname2);
  error = dlerror();
  if (error)
    printf("Error: %s\n", error);
  else
  {
    result = add(10, 20);
    printf("The sum is: %i\n", result);
  }

    /* get printme function and call it */
  printme = (PRINTME)(intptr_t)dlsym(lib, fname1);
  error = dlerror();
  if (error)
    printf("Error: %s\n", error);
  else
    printme("Print this!");

    /* library no longer needed */
  dlclose(lib);

  return 0;
}
Output:
The sum is: 30
Hello from library: Print this!