Bonjour à tous! Bon, mon problème me dépasse un petit peux...

J'ai créer une classe qui me permet de gérer des fichier XML selon mon besoin. Pas de problème de ce côté là. Comme vous allé le voire, j'utilise un TXmlDocument créer dynamiquement pour éditer mes fichier XML.

Voici un partie du code source de ma classe :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 
//---------------------------------------------------------------------------
 
#ifndef TXmlCreatorH
#define TXmlCreatorH
#include <vcl.h>
#include <msxmldom.hpp>
#include <XMLDoc.hpp>
#include <xmldom.hpp>
#include <XMLIntf.hpp>
//---------------------------------------------------------------------------
class TXmlCreator
{
        public :
                //Constructeur. Il permet de récupérer les informations pour la création du fichier XML
                __fastcall TXmlCreator( AnsiString lProcess, AnsiString lOutPath, AnsiString lRoot,
                                        AnsiString lLevel, AnsiString lFrom);
                //Destructeur
                __fastcall ~TXmlCreator(void);
 
                //Méthode appelé pour l'ajout d'image
                void __fastcall addImageToLine(AnsiString idLine, AnsiString imagePath,  int errorCode, AnsiString info);
                void __fastcall addImageToLine(AnsiString imagePath, int errorCode, AnsiString info);
                void __fastcall saveXmlFile(void);
 
        private :
 
                //Méthode permettant la création d'un fichier XML
                void __fastcall createFile(void);
 
                //Méthode qui permet de créer les noeud principaux
                void __fastcall createBaseNode(void);
 
				//Méthodes appelé pour ajouter une ligne
				AnsiString __fastcall findIdImage(AnsiString imagePath);
				int __fastcall indexOfLineFromId(AnsiString idLine);
				void __fastcall addLine(AnsiString idLine);
 
                //Attribut utilisé pour la création dynamique d'un TXMLDocument
                TXMLDocument *XMLDoc;
                _di_IXMLDocument iXML;
                _di_IXMLNode node;
 
                //Attribut utilisé pour récupérer les informations nécessaire pour créer le fichier XML
                AnsiString mProcess;
                AnsiString mOutPath;
                AnsiString mRoot;
                AnsiString mLevel;
                AnsiString mFrom;
                int mTotal;
 
 
 
};
#endif
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 
//Constructeur
__fastcall TXmlCreator::TXmlCreator( AnsiString lProcess, AnsiString lOutPath,
                                     AnsiString lRoot, AnsiString lLevel, AnsiString lFrom)
{
        /*
        **Lorsque l'on créer une instance d'un TXmlcréator, il faut lui passer 5 paramètres :
        **
        **      -OutPath :     qui représente le chemin d'accès du fichier xml à créer
        **      -Process :      qui représente le chemin d'accès au script
        **      -Root :         qui représente le chemin de la source utilisé pour la création du fichier
        **      -Level :        qui représente le niveau de priorité du traitement (Low, Normal, High)
        **      -From :         qui représente le type de source (base, socket...)
        **
        **      La variable total représente le nombre de ligne dans le fichier xml.
        **      Elle s'incrémente automatiquement à l'ajout d'une ligne.
        */
 
        mOutPath        = lOutPath;
        mProcess        = lProcess;
        mRoot           = lRoot;
        mLevel          = lLevel;
        mFrom           = lFrom;
        mTotal          = 0;
 
        //Appel la méthode privée createFile().
        createFile();
 
        /*
        **Après avoir créer le fichier xml :
        **
        **      -On créer une nouvelle instance d'un TCMLDocument
        **      -On lui attribut un _di_IXMLdocument
        **      -On charge le fichier xml que l'on a préalablement créé.
        **      -On affecte le noeud principale à un _di_IXMLnode
        */
        XMLDoc = new TXMLDocument("");                 //instance d'un TCMLDocument.
        XMLDoc->GetInterface(iXML);                    //attribution d'un _di_IXMLdocument.
        iXML->LoadFromFile(mOutPath);                  //chargement du fichier.
        node = iXML->DocumentElement;                  //affectation du noeud principale.
 
        createBaseNode();                               //Appel la méthode privée createBaseNode().
}
 
//Destructeur
__fastcall TXmlCreator::~TXmlCreator(void)
{
        if (XMLDoc)     delete XMLDoc;  XMLDoc = NULL;          //A la destruction de l'objet, on désallou le TXMLDocument
}
 
void __fastcall TXmlCreator::createFile(void)
{
        /*
        **Cette méthode s'occupe de créer le fichier xml sur le disque, à l'endroit désiré.
        **Elle créer aussi la balise principale <Setup>
        */
 
        TFileStream* xmlFile = new TFileStream( mOutPath, fmCreate);                    //création du fichier
        char *writeFileBuffer = new char[16];                                           //création d'un buffer pour écrire dans le fichier
        writeFileBuffer = "<setup>\n</setup>";                                          //on rempli le buffer affin de créer manuellement une balise
        xmlFile->WriteBuffer(writeFileBuffer, 16);                                      //on écri le contenu du buffer dans le fichier
        if (xmlFile)            delete xmlFile;                 xmlFile = NULL;         //on désallou la mémoire utilisé pour la fonction
        if (writeFileBuffer)    delete writeFileBuffer;         writeFileBuffer = NULL;
}
 
void __fastcall TXmlCreator::createBaseNode(void)
{
        /*
        **Le but de cette méthode est de créer les noeud principaux (root, from, level, total, lines)
        */
 
        node->AddChild("info", 0);
        node->AddChild("lines", 1);                                             //Création du noeud info
        node->ChildNodes->Nodes[0]->SetAttribute("process",mProcess);            //Ajout de l'atribut process qui prend la valeur mProcess
        node->ChildNodes->Nodes[0]->SetAttribute("root",mRoot);
        node->ChildNodes->Nodes[0]->SetAttribute("from",mFrom);
        node->ChildNodes->Nodes[0]->SetAttribute("level",mLevel);
        node->ChildNodes->Nodes[0]->SetAttribute("total",mTotal);
}

Je n'ai pas écris la totalité du fichier 'TXmlCreator.cpp' par souci de clarté. Si mon code vous intéresse, demandé le moi!


Le problème ce situe au niveau du destructeur.J'ai une violation d'accès mémoire au moment du delete.
J'ai commencé par voir au niveau de la documentation du TXmlDocument, et je suis tombé la dessus :

Citation : Documentation TXmlDocument
Disposes of a TXMLDocument object.

__fastcall virtual ~TXMLDocument(void);

Description

It is not necessary to explicitly free a TXMLDocument component. If the component is created with an Owner, that Owner handles the task of freeing the document. If the component is created without an Owner, it is freed automatically when the reference count on its IXMLDocument interface drops to zero.
Citation : Documentation TXmlDocument
When TXMLDocument is created without an Owner, it behaves like an interfaced object. That is, when all references to its interface are released, the TXMLDocument instance is automatically freed. When TXMLDocument is created with an Owner, however, it behaves like any other component, and is freed by its Owner. When you add a TXMLDocument component from the component palette to a form or data module, it is automatically created with an Owner. When the TXMLDocument component is created using the global LoadXMLDocument function (or by a function that the XML Data Binding wizard generates to return the root node of the document), the function creates a TXMLDocument instance without an Owner.
Si je comprend bien, ces paragraphes disent que le TXmlDocument ce fait détruire par son owner si il en possède un (le mien n'en a pas) et que dans le cas où il n'en à pas, il ce détruit lorsque son compteur d'interface arrivais à 0.

Là je me suis dis cool, je n'ai qu'à supprimer l'interface iXML! J'ai trouvé une méthode 'release()' qui appartient à iXml, et qui renvoie le nombre d'interface restante! Le problème c'est que cette méthode me renvoie 1, et non pas 0. Il y a donc encore une interface.

Je suis pas très doué en programmation mais je trouvais que faire comme ceci était un peu 'moyen' :-°

Du coup j'ai cherché sur internet, je suis tombé sur un post intéressant :

http://www.developpez.net/forums/d30.../txmldocument/

Bon, alors là, ça me dépasse COMPLÈTEMENT!

Quelqu'un pourrais me filer un petit coup de main?

Merci à vous!