Un petit exemple pour montrer comment on fait : ici les plugins contiennent une fonction qui affiche un message.

Les plugins

Sources

le fichier source fr.c ci-dessous affiche le message en français
#include <stdio.h>
void manger() {
  printf("Miam Miam !\n");
}
et son homologue en.c fait la même chose, en anglais
#include <stdio.h>
void manger() {
  printf("Yummy yummy!\n");
}

Compiler les plugins

On les compile sous forme de modules partagés, avec le suffixe .so (shared objects). Voila le bout de Makefile qui s'en occupe :
plugins: fr.so en.so
%.so: %.c
        gcc -shared -nostartfiles $^ -o $@

Le programme principal

Utilisation

Le programme principal ./main lancera la fonction manger() d'un des modules. Pour faire très simple ici, on se contentera de passer le chemin d'accès du module en paramètre, exemple :
$  ./main  ./fr.so

Le source

Le source est grandement inspiré de la page de manuel de dlopen(). Dans les grandes lignes :
  • le fichier plugin sélectionné est chargé par dlopen()
  • dlsym() va y chercher la fonction manger(), dont l'adresse est mise dans la variable fun (un pointeur sur une fonction, bonjour le transtypage).
  • la fonction est lancée
  • le plugin est refermé
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    void *handle;
    char *error;
    void (*fun)();

    if (argc != 2) {
      fprintf(stderr, "Usage: %s fichier\n", argv[0]);
      exit(EXIT_FAILURE);
    }

    handle = dlopen(argv[1], RTLD_NOW);
    if (!handle) {
        fprintf(stderr, "%s (plugin manquant ?)\n", dlerror());
        exit(EXIT_FAILURE);
    }

   dlerror();  /* Clear any existing error */

    *(void **) (&fun) = dlsym(handle, "manger");
    error = dlerror();
    if ((error != NULL) {
      fprintf(stderr, "%s: %s\n", argv[0], error);
      exit(1);
    }

    (*fun) ();   /* lancement */
    dlclose(handle);
    return 0;
}

Compiler le programme principal

Encore un petit bout de Makefile
all: main plugins

main: main.c
        gcc -rdynamic -o main main.c -ldl