COM : Prenière approche.

Télécharger le code source

Définition :
COM – Component Object Model ( Model par Objet Composant (oui je sais c moyen))

Justification :
Si vous avez déjà voulut exporter une classe via une dll, vous devez savoir quelle douleur cela à été ( jouer avec les dllexport / dllimport ). De plus inclure le .lib généré est obligatoire. Dans ce cas COM peut vous être utile. Pour commencer on va juste étudier ce problème. Sachez que COM est une architecture hyper complexe mais en retour les possibilité sont innonbrables. D'ailleur dans ces articles nous ne ferons pas de COM, on utilisera uniquement certains mécanismes qui ont un rapport qualité/prix correct pour la programmation de jeu.

Théorie :
La théorie de base c que plutôt que de créer vous même l’objet vous allez demander à la dll qui contient cet objet de le créer, cela vous évite de savoir comment le créer.

exemple :
On créer les projets exemple.dll et exemple.exe
Note: cet exemple est théorique, pour un code qui marche se référer au projet ci-joint.

//////////////////////
// dllexports.h
//    * en-tête principal de exemple.dll
//////////////////////

// définition de la classe CStuff qui sert pas à granbd chose
interface CStuff  // Definit comme struct qui est une classe qui par défaut est publique
{
    virtual DoSomeStuff();
};

// définition de la fonction
extern void CStuff* CreateStuff();

// EOF (End Of File)

//////////////////////
// dllmain.cpp
//    * fichier principal de exemple.dll
//////////////////////

#include "windows.h"  // Les crochets marchent pas en html
#include "dllmain.h"

// On implémente la méthode de CStuff
CStuff::DoSomeStuff()
{
	MessageBox( 0, "Je fait des choses." , "Message de la dll!", MB_ICONERROR);
}

// On implémente la fonction CreateStuff
// Sert à créer une instance de l'objet CStuff
void CStuff*  CreateCStuff()
{
    CStuff* lpStuff = new CStuff;
    return lpStuff;
}

// EOF

;;;;;;;;;;;;;;;;;;;;;;
;; define.def
;;    * fichier de controle des exportation  de la dll
;;    * sert à créer le .lib
;; NOTE: il faut des ; et non pas // pour faire des commentaires
;;;;;;;;;;;;;;;;;;;;;;
EXPORTS
		CreateCStuff   ; On exporte juste cette fonction
;; EOF


/////////////////////
// main.cpp
//   * fichier principal de exemple.exe
//   * il faut aussi lier le projet à exemple.lib produit par ladite dll
/////////////////////

#include "../dllmain.h"

int WinMain( ... )
{
    // On crée l'objet CStuff
    CStuff* lpStuff = CreateStuff();

    // On fait qqchose avec cet objet
    lpStuff->DoSomeStuff();

    return 0;
}

Ok, voilà comment ca se présente. Les attentifs vont me répondre que j'oublie un peu de désalouer la mémoire prise par cet objet. Sur le coup ils ont raison point de delete lpStuff. Les plus ardis d'entre-vous tenterons de le mettre à la fin WinMain, mais en mode debug un belle assertion les préviendra que ca marche pas (ceux qui font pas de débug remarquerons rien mais ca ne marchera quand même pas :). Ben oui du à la gestion de la mémoire de windows, la mémoire alloué dans une dll doit être désalloué dans cette même dll.

On patche le modèle
Bon alors que faire, la réponse est évidente, il faut mettre le delete dans la dll. Pour ce faire on va implémenter une méthode Release() sur cet objet de la fassons suivante. Il faut bien sur que l'application l'appelle pour que ca marche.

CStuff::Release()
{
    delete this;
}

Enguise de conclusion
A ce niveau, nous avons donc réussit à exporté une classe d'une dll de façon simple. La prochaine fois nous étudierons la gestion autonome de durée de vie des objets.