Écrire des greffons (plugins) en C
Par Michel Billaud, samedi 6 décembre 2008 à 14:28 :: Bidouilles :: #36 :: rss
De nos jours beaucoup de logiciels sont conçus sous forme d'un programme principal auquel l'utilisateur peut ajouter ou enlever des modules, appelés plugins (greffons).
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
Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.