Citation
Basile STARYNKEVITCH
D'abord, je ne comprends pas bien le verbe
"instancier un nouveau plugin" dans ta phrase. On
n'instancie pas un plugin (à partir de quelque
chose qui en serait le patron ou le moule), on le
charge.
C'est une petite erreur de relecture O:-)
Je voulais dire instancier un objet.
Citation
Basile STARYNKEVITCH
Le plugin existe préalablement: il a dû
être compilé, à partir de son code source en C++,
avecg++ -fPIC -shared plugin.cc -O -o plugin.so
Ensuite tu le charges (une fois) dans ton
programme avecdlh = dlopen("./plugin.so",
RTLD_NOW);(mais lis bien la page de man de dlopen,
il y a des subtilités importantes).
Jusque là, j'y arrive (il me semble que RTLD_NOW soit dans mon cas mieux que RTLD_LAZY, mais je ne saisis pas vraiment dans quel cas RTLD_LAZY est plus approprié.)
Citation
Basile STARYNKEVITCH
il faut que ça soit un
extern "C". Tu dois documenter et définir la
sémantique de cette fonction.
Tu vas alors chercher par dlsym le pointeur vers
cette fonction, avecint
(*fillwinptr)(fltk::Window*);
fillwinptr = dlsym(dlh, "fillwindow");
if (!fillwinptr) {cerr << "dlsym failed
<< dlerror() << endl; exit(1);};
Quand tu as besoin de cette fonction, tu
l'appelles via son pointeur.
Je vois le principe dont tu me parles. La procédure est plus complexe à mettre en place que mon idéal. Le comportement que j'aimerais avoir est le suivant (en algorithme) :
Plugin est une classe qui possède une méthode run();
main possède un objet "gui" de portée globale (il a été défini avant le main()).
gui possède un élément de type Plugin* (gui->plugin)
1) demande de chargement du plugin
2) constructeur du plugin : création d'un nouvel objet :
Plugin *monplugin=new Plugin();
3) affectation de monplugin à l'objet principal : gui->plugin=monplugin (là, ça ne fonctionne pas)
4) fin du constructeur du plugin
5) appel de gui->plugion->run();
Si selon toi ce comportement n'est pas possible, je me rabattrai sur l'appel simple de fonction.
Enfin, tu peux décharger le plugin à la fin avec
dlclose (qui ferait exécuter les fonctions
destructeurs du plugin).
Citation
Basile STARYNKEVITCH
Si tu voulais (je n'ai pas compris pourquoi tu
veux des plugins) charger un code particulier à
chaque exécution, tu pourrais par exemple générer
ce code en C ou C++, le compiler par un appel
system(3) à g++, puis le charger. Tu pourrais
aussi méta-programmer ainsi avec libjit ou llvm ou
GNU lightning. Avec de telles approches
(intéressantes mais difficiles) il faudrait passer
par un AST (abstract syntax tree). Mais je ne
crois pas que tu veuilles faire ça (à dire vrai,
je n'ai pas compris quelle est ta motivation pour
les plugins).
Voici toute l'histoire : je fais un peu de photo, et je n'ai pas trouvé de logiciel open source permettant de les travailler avec un seul outil, et ayant une interface optimisée pour le traitement des photos. Pour moi, Digikam est inexploitable (on passe trop de temps à aller dans les menus pour changer les paramètres de base d'une photo), Rawstudio pourrait être bien, mais il a des défauts de conception : il perdent du temps à réécrire ce qui existe déjà, et moins bien (ils ont codés eux-même les rotations, par palier de 90°. On ne peut pas redresser une photo de quelques degrés ; ils ont recodé les fonctions de contraste, luminosité,...). Par contre, il a d'autres fonctions très très intéressantes (mais il manque trop de choses pour être utilisable pour moi).
Pour éviter de réinventer la roue, j'utilise la librairie libraw pour ouvrir les fichiers au format raw (cette partie aurait été trop compliquée pour moi, les spécifications des fichiers étant inexistante) ainsi que magick++ (la version librairie C++ de Image Magick, qui peut faire beaucoup de travail).
Je me suis rajouté des contraintes pour tenter de bien définir les fonctions de bases :
* utilisation de librairies existantes pour :
** avoir moins de code à maintenir
** gagner du temps de développement (par exemple, une rotation se traduit par un simple image.rotate(double degree).
* multithreading pour la création des imagettes (le nombre de threads est configurable. Cela permet sur ma machine d'ouvrir 20 fichiers en parallèle en utilisant 1Go de RAM. C'est gourmand, mais donne de bonnes performances. L'ouverture de fichiers raw implique des calculs qui sont plus long que le temps de lecture d'un fichier)
* multilingue (cette partie là n'est pas encore abordée)
* basée sur des plugins pour les outils de traitement d'image. L'utilisation de plugins permettra plusieurs choses :
** l'utilisateur pourra ne charger que les fonctions dont il a besoin : son interface ne sera pas chargée de fonctions qui ne lui servent pas
** l'utilisateur pourra ordonner le chargement des plugins : l'interface sera adaptée à sa façon de travailler
** un développeur pourra écrire son propre plugin et le diffuser. Ce sera plus simple pour motiver les contributions : pas besoin de modifier le programme principal pour rajouter des fonctionnalités.
Bref, je complexifie au départ pour pouvoir travailler plus vite par la suite.
Tu as lu les docs. Tu es devenu un informaticien. Que tu le veuilles
ou non. Lire la doc, c'est le Premier et Unique Commandement de
l'informaticien.
-+- TP in: Guide du Linuxien pervers - "L'évangile selon St Thomas"