Comprendre et savoir faire des plug-ins

Description

Vous êtes vous déjà posé la question de savoir ce que sont les plug_ins et
comment ils marchent?
Voici un exemple très simple qui nous permet de comprendre le système

L'idée du PlugIn est de développer une application principale (un exe)
sans avoir la complète implémentation des différentes fonctionnalités
et de laisser une bonne dose de variabilité à l'application .
Plutôt que de tout coder dans l'application principale, on va utiliser
un système de modules externes (plug-ins - sous forme de DLLs)
chargés de la réalisation des différentes fonctionnalités.
Ainsi, en run-time, il sera possible d'utiliser un plugIn1 ou bien un plugIn2...
On pourra même permettre le développement personnalisé de plugIns supplémentaires
après le développement, la compilation et l'installation de l'application
Voyons un exemple d'implémentation à base de DLLs

Etape 1 : on définit un cadre général.
Ce que devra faire l'application : le "QUOI"
Exemple:
l'application devra être capable d'écrire une chaîne de caractères qu'on lui passera.

Ceci nous définit un protocole de collaboration (une interface diront certains)
entre l'application et le plug_in.
On se limitera dans cet exemple à une méthode
"void ecrit(char* s)"

Remarquons qu'il serait nécessaire/utile de prévoir dans l'application les fonctions de recherche
des plug-ins, de chargement/déchargement ainsi que leur activation.
Ces méthodes devront être implémentées par tous les plug-ins
On pourrait les nommer "charger" et "decharger" (non fait ici)
handle charger(string nomPlugIn) et decharger(handle), puis activer(handle)

Etape 1 bis:
On donne une implémentation par défaut de la fonctionnalité
C'est pratique si l'utilisateur n'a pas de plug-in, il faut quand même que ça marche !
Ici, on écrira simplement le texte sur la console

Etape 2 : on développe des variations sans modifier l'application principale
sous la forme de Plug-Ins
Les variations seront chargées du "COMMENT" faire.
Exemple, écrire en reverse vidéo, ecrire en rouge sur fond bleu, écrire en double, etc...
L'exemple choisit étant très simple, les variations sont assez limitées.
Mais dans un monde graphique, on y verra tous les Skins de WinAmp, etc...
les logiciels écrits sous forme de plug-ins pour les environnements de développements...

Etape 3 : on teste
PlugIn : 0 (par défaut) => écriture normale
PlugIn : 1 => écriture en reverse vidéo.
PlugIn : 2 => ecriture en rouge sur fond bleu + rouge sur fond vert.

A quoi ça sert ? vous pouvez maintenant développer vous même votre propre PlugIn
auquel je n'ai pas encore pensé... écrire en italique, en gros caractères,...
à l'envers, ... en relief (enfin quand les consoles le permettront!).

Source / Exemple :


//**************************
// le main.cpp (sous forme d'EXE)
//**************************
#include <windows.h>
#include <iostream.h>
//Remarquons qu'il n'y a pas d'include de "plugin.h"
// ni de link avec plug1.lib ou plug2.lib...
// => l'exe ne connait pas les plugins

void Erreur(char* p){cout << p << endl; exit(1);} 

//déclaration du type : pointeur de fonction (il pointera sur "ecrire")
typedef void (*PF) (char*);

int main()
{
	int n=0;
	char plugIn[20]={0};
	char texte[80]={0};	
	HMODULE hm = 0;
	do
	{
	cout << endl<<"donner le nom du module PlugIn desire (0 pour aucun, x pour fin)" << endl;
	cin >> plugIn;
	if (!strcmp(plugIn,"x")) return 0;
	if (strcmp(plugIn,"0"))
	{
		if(hm) //libération de l'ancien plug_in
		{
			int rc = FreeLibrary(hm);
			if (!rc) Erreur("FreeLibrary");
			hm=0;
		}
		hm = LoadLibrary(plugIn);
		if (!hm) 
		{
			cout << "module " << plugIn << ".dll non trouve..." << endl;
			continue;
		}
	//tous les plug-ins auront la méthode ecrire(string)
	PF ecrire = (PF)GetProcAddress(hm, "ecrire");
	if (ecrire==NULL) Erreur("echec GetProcAdress : plugin non compatible...");
	cout << "donner votre texte : ";
	cin >> texte;
	ecrire(texte);
	}
	else
	{
	cout << "donner votre texte : ";
	cin >> texte;
	cout << texte;
	}
	cout << endl;
	if (!(++n%4))//efface l'écran pour éviter de gérer le scroll du buffer
	{
		Sleep(2000);
		system("cls");
	}
}
	while (true);
	return 0;
}

//****************************
// le plug1.cpp (sous forme de DLL)
//****************************
#include <iostream.h>
#include "plugin.h"

//le DllMain est généré par le compilateur en cas d'absence

extern "C" PLUGIN void ecrire(char* texte)
{
HANDLE hStdout; 
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 

	//Récupérer un handle sur la console
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 

    //Sauvegarder les anciennes couleurs. 
    GetConsoleScreenBufferInfo(hStdout, &csbiInfo);

	WORD wOldColorAttrs = csbiInfo.wAttributes; 
    //Basculement en reverse vidéo
	SetConsoleTextAttribute(hStdout, BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | COMMON_LVB_REVERSE_VIDEO); 
	
	//Ecriture du texte
	cout << texte;
	cout.flush();//important

    //Restorer les couleurs originelles. 
    SetConsoleTextAttribute(hStdout, wOldColorAttrs);
}

//**************************
// le plugin.h
//**************************
#include <windows.h>

#ifdef PLUGIN_EXPORTS
#define PLUGIN __declspec(dllexport)
#else
#define PLUGIN __declspec(dllimport)
#endif

extern "C" PLUGIN void ecrire(char*);

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.