[XML]Utilisation de tinyXML sous Visual Studio 2005[résolu]

K-lo
[XML]Utilisation de tinyXML sous Visual Studio 2005[résolu]

Je doisvous embeiter avec mes problèmes du a MS VC++ :(
Désolé mais si mon problème peut aider d'autres pourquoi devraisje hésiter :P

Bref j'ai tester le parsage de fichier XML via TinyXML

Pas de problème pour un projet vide ou un projet console W32.

La où sa coince c'est lorsque je veux compiler avec un projet nécessitant les MFC (console w32 en inclant les entetes MFC).
Un conflit de bibliothèque :

1>libcmtd.lib(crt0.obj) : error LNK2005: _mainCRTStartup déjà défini(e) dans msvcrtd.lib(crtexe.obj)
1>libcmtd.lib(errmode.obj) : error LNK2005: ___set_app_type déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: _exit déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: __exit déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: __cexit déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: __amsg_exit déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0dat.obj) : error LNK2005: __initterm_e déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(setlocal.obj) : error LNK2005: __configthreadlocale déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(tidtable.obj) : error LNK2005: __encode_pointer déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(tidtable.obj) : error LNK2005: __decode_pointer déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: __CrtSetCheckCount déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(winxfltr.obj) : error LNK2005: __XcptFilter déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(crt0init.obj) : error LNK2005: ___xi_a déjà défini(e) dans msvcrtd.lib(cinitexe.obj)
1>libcmtd.lib(crt0init.obj) : error LNK2005: ___xi_z déjà défini(e) dans msvcrtd.lib(cinitexe.obj)
1>libcmtd.lib(crt0init.obj) : error LNK2005: ___xc_a déjà défini(e) dans msvcrtd.lib(cinitexe.obj)
1>libcmtd.lib(crt0init.obj) : error LNK2005: ___xc_z déjà défini(e) dans msvcrtd.lib(cinitexe.obj)
1>libcmtd.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(invarg.obj) : error LNK2005: __invalid_parameter déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(invarg.obj) : error LNK2005: __invoke_watson déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(mlock.obj) : error LNK2005: __lock déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(mlock.obj) : error LNK2005: __unlock déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>libcmtd.lib(dbgrptw.obj) : error LNK2005: __CrtDbgReportW déjà défini(e) dans msvcrtd.lib(MSVCR80D.dll)
1>LINK : warning LNK4098: conflit entre la bibliothèque par défaut 'msvcrtd.lib' et les autres bibliothèques ; utilisez /NODEFAULTLIB:library
1>msvcrtd.lib(cinitexe.obj) : warning LNK4098: conflit entre la bibliothèque par défaut 'libcmtd.lib' et les autres bibliothèques ; utilisez /NODEFAULTLIB:library
1>C:\Projet\Debug\Projet.exe : fatal error LNK1169: un ou plusieurs symboles définis à différentes reprises ont été rencontrés
1>Le journal de génération a été enregistré à l'emplacement "file://c:\Projet\Debug\BuildLog.htm"
1>InterConnexion - 24 erreur(s), 2 avertissement(s)

Dsl j'ai toujours des problèmes avec ces bibliothèques :(.

fredericmazue

Quote:
Je doisvous embeiter avec mes problèmes du a MS VC++

Mais non, ce forum est fait pour ça :)

Quote:
La où sa coince c'est lorsque je veux compiler avec un projet nécessitant les MFC

Le message d'erreur est clair ;)
Je résume: l'éditeur de leins voit deux main au sens MFC du terme.
Je pense que quand tu as compilé ta lib (ou en incorporant ses fichiers sources à ton projet), tu as inclus un bout de code de test qui déclare un main. Ou quelque chose comme ça. Tu le trouves, tu le vires, et AMHA, ça marche :)

K-lo

fredericmazue wrote:

Le message d'erreur est clair ;)
Je résume: l'éditeur de leins voit deux main au sens MFC du terme.
Je pense que quand tu as compilé ta lib (ou en incorporant ses fichiers sources à ton projet), tu as inclus un bout de code de test qui déclare un main. Ou quelque chose comme ça. Tu le trouves, tu le vires, et AMHA, ça marche :)

Bah je veux bien mais le hic c'est que je le trouve pas :

voilà comment j'ai procédé :
J'ai télécharger depuis le site officiel la bibliothèque.
Dedans il faut compiler le projet (il est pas compatible vc8 mais le projet peut etre adapté)
Je compile et il me sort un dossier DEBUG_STL (pour STL) et DEBUG (sans STL) selon si on veut utiliser la STL ou non.
Contenant le fichier .lib qu'il faut inclure dans le projet.

Je lie avec VC++ le dossier DEBUG (j"utilise la STL mais via DEBUG_STL
et tinyxmld_STL.lib j'ai plein d'erreur de linkage même avec un projet simple)
où se troue donc tinyxmld.lib.

Bref je lis le dossier où se trouve mes sources (surtout le .h)
et j'inclu le fichier tinyxml.h dans mon projet.

Por faire simple :D :
#1 compilation
#2 liaisons du dossier où se trouve tinyxml.h et tinystr.h avec le dossier include de VC++
#3 liaisons du dossier où se trouve tinyxmld.lib (DEBUG/)avec le dossier bibliothèque de VC++
#4 ajout dans le code de pragma comment (lib,"tinyxmld.lib") et de #include

Comme je le disais ^pour un projet simple pas de pb mais pour ls MFC ça coince et je vois pas le bout de code qui pourrait être considéré comme main...

fredericmazue

Bon poussé par la compassion devant tant d'em...., j'ai booté un Windows (jusqu'où je pousse l'abnégation quand même....) et j'ai essayé par moi même... et je suis tombé sur le même problème exactement. Si ça peut te consoler...

Et en voyant le pb de mes petits yeux porcins, j'ai immédiatement compris. MFC! Bon sang mais c'est bien sûr!
C'est même un p¤¤¤¤¤ de bug très connu.
Ce que tu rencontres se produit quand des libraries ne sont pas liées dans le bon ordre. Normalement stdafx.h assure le bon ordre MAIS tinyXML ne fait aucun usage de stdafx.h donc en voulant te servir de la lib avec MFC tu te cognes la tête dans le problème immanquablement.

Je n'ai malheureusement pas le temps de t'expliquer mieux, mais tu vas trouver des explications et des workarounds là:

http://support.microsoft.com/kb/148652

Je pense que cela suffira pour que tu t'en tires.

Une autre solution toute simple (le plus simple ?), vu la toute petite taille de la lib, c'est d'intégrer ses fichiers sources dans ton projet

MFC :!: :twisted: :twisted: :twisted:
¤¤¤¤ #### :!: :!:
Mais faut quand même être fou masochiste pour coder avec ce truc dépassé. Une des pires librairies de l'univers connu et inconnu. C'est tellement mauvais que ça justifie presque l'existance de Java :twisted:
Presque...

Tu peux pas te servir d'une librairie propre sur elle ? Ce n'est pourtant pas ce qui manque et tu y gagnerais. La preuve.

Bon j'espère t'avoir aidé à avancer.

Au plaisir :)

K-lo

Un GRAND MERCI A TOI !

Je vais regarder de maniere très approfondie.

Désolé de ce dérangement !

Edit : j'ai intégré la bibliothèque au projet et cela compile bien :) ! Encore merci et dsl de t'avoir fais bouter sur windows :oops:

fredericmazue

Quote:
Encore merci et dsl de t'avoir fais bouter sur windows

Je m'en remettrai :)

Je suis heureux que ton pb soit résolu.

Au plaisir :)

K-lo

Je sais pas si c'est propre à TinyXML mais c'est en utilisant cette bibliothèque que je me suis rendu compte de quelque chose :
Le Mot réservé delete sur la classe TinyXmlNode fait planté le programme.
Ce qui est normale puisque la plupart du temps on ne fait pas d'appel au mot réservé new. Mais est-ce une bonne chose ? Est-ce que ne pas utilisé new et delete va pas poser des problèmes de fuite de mémoire ou autre ?
Sachant que la plupart du temps les fonctions sont récursives afin accéder aux différents noeuds d'un fichier XML.

Quote:

TinyXmlNode *tiNode1 = doc->RootElement();
TinyXmlNode *tiNodeFils = tiNode1->FirstChild();
if(tiNodeFils){
std::cout<Value();
}

Je sais je suis un peu pénible au niveau de ces problèmes lié à la mémoire. Mais je domine pas le sujet :oops:

fredericmazue

Quote:
Le Mot réservé delete sur la classe TinyXmlNode fait planté le programme.

delete pointeur_sur_TinyXmlNode tu veux dire ? Par exemple delete tiNodeFils ?
Si ça plante, c'est que le pointeur n'était pas valide, pour une raison ou une autre. Ou dans ton cas sans doute que delete est appelé deux fois, une fois par toi, une fois par la librairie
Quote:
Ce qui est normale puisque la plupart du temps on ne fait pas d'appel au mot réservé new. Mais est-ce une bonne chose ? Est-ce que ne pas utilisé new et delete va pas poser des problèmes de fuite de mémoire ou autre ?

Je ne sais pas exactement car tu ne montres pas de code et aussi et surtout TinyXml est (très) loin de mes préoccupations en ce moment.
MAIS, je dirais quand même que c'est sans doute une bonne chose dans ce cas. Quand tu écris:
TinyXmlNode *tiNodeFils = tiNode1->FirstChild(); 

La librairie te renvoie un pointeur, MAIS pas forcément en créant une instance. Je dirais même probablement pas. Bref par cette ligne de code tu as une adresse et c'est tout. A priori tu ne dois pas faire de delete dessus, c'est la librairie qui va s'en charger quand tu vas faire un delete sur la racine par exemple. Si tu as déjà fait un delete avant sur un noeud, il y aura un pointeur invalide quelque part dans l'arborescence XML et ça va planter quand la librairie voudra effacer le tout.
Sans compter que peut être, la librairie a implémenté un allocateur à elle.

Enfin tout ça c'est des suppositions, faut regarder ce que raconte la doc à ce niveau et éventuellement un peu de ton code. Mais au pif, je dirais volontiers qu'il est normal de ne pas invoquer delete dans ce cas, et ceci sans avoir de fuites mémoire pour autant :)

K-lo

Quote:
La librairie te renvoie un pointeur, MAIS pas forcément en créant une instance. Je dirais même probablement pas. Bref par cette ligne de code tu as une adresse et c'est tout. A priori tu ne dois pas faire de delete dessus, c'est la librairie qui va s'en charger quand tu vas faire un delete sur la racine par exemple. Si tu as déjà fait un delete avant sur un noeud, il y aura un pointeur invalide quelque part dans l'arborescence XML et ça va planter quand la librairie voudra effacer le tout.


C'est la confirmation que j'attendais :D
Juste pour être sur :p

Quote:
e ne sais pas exactement car tu ne montres pas de code

void recherche(TiXmlNode *ti, 	std::vector<std::string>& out)
{
	TiXmlNode  *tNode;

	if(ti != NULL){
		tNode = ti; 
	}else{
		tNode = this->docFich->RootElement();
	}
	tNode = tNode->FirstChild();
	if(!tNode){return;}
	
	while(tNode->ToElement()){
if(std::string(tNode->Value()) == std::string("baliseRecherchee"))){
			if(tNode->FirstChild()){
				out.push_back(std::string(tNode->FirstChild()->Value()));
			}
		}
		recherche(tNode, out);
		if(tNode != tNode->Parent()->LastChild()){
			tNode = tNode->NextSibling();
		}else{
			break;
		}
	}

	return;
}