Stricmp error

Résolu/Fermé
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 - 30 juin 2013 à 04:54
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 - 30 juin 2013 à 18:55
Bonjour,

Je ne comprend pas pourquoi il y a une erreur:

int GetProcessID(char* name) {
		HANDLE tlh = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		PROCESSENTRY32 prEntry;
		prEntry.dwSize = sizeof(PROCESSENTRY32);

		int id = 0;

		Process32First(tlh, &prEntry);
		do {
			if(stricmp(prEntry.szExeFile, name) == 0) {
				id = prEntry.th32ProcessID;
			break;
			}
		} while(Process32Next(tlh, &prEntry));

		CloseHandle(tlh);
		return id;
}


error C2664: 'stricmp' : impossible de convertir le paramètre 1 de 'WCHAR [260]' en 'const char *'
1> Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction

J'ai déjà lu tout les truc sur MSDN j'ai rien compris...

2 réponses

Hxyp Messages postés 401 Date d'inscription vendredi 28 janvier 2011 Statut Membre Dernière intervention 27 avril 2014 54
Modifié par Hxyp le 30/06/2013 à 11:02
Bonjour,
le problème est dû au fait que les types sont différents ( https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/ns-tlhelp32-processentry32?redirectedfrom=MSDN ) :
dans la struct PROCESSENTRY32, szExeFile est un WCHAR.
Et ça c'est le prototype de stricmp ( https://www.microsoft.com/en-us/download/details.aspx?id=55984 ):
int _stricmp(
const char *string1,
const char *string2
);
stricmp ne prend pas de WCHAR en paramètres mais des char la différence de taille entre les types les rend incompatible regardez ( http://msdn.microsoft.com/en-us/library/windows/desktop/gg269344%28v=exchg.10%29.aspx ) :
typedef unsigned short WCHAR;
"Data Types WCHAR A 16-bit Unicode character."
Du coup on ne peut pas comparer un tableau de WCHAR est un de char c'est comme comparer un tableau de short et de char.
Si le char fait 8bits et que le WCHAR fait 16bits vous pouvez comprendre que ça pose un problème lorsque stricmp qui utilise des pointeurs type char* pour faire la comparaison il va se balader dans les tableau avec un décalage utilisant la taille d'un char du coup s'il tombe sur un wchar qui fait 2char il va comparer deux char contre un seul wchar.
Vous pouvez tenter le cast comme indiqué avec de la chance ça peut marcher seulement faire un cast dans ces conditions revient à utiliser la chance pour que ça marche et ça peut bugger du jour au lendemain car windows autorise des noms de fichiers etc utilisant l'ucs2 (avec des WCHAR) donc si vôtre programme venait à être exécuté sur un système windows russe, jap,etc.. bah ça peut planter car la moitié d'un wchar d'un symbol jap ou russe peut être l'équivalent d'un char etc dans tout les cas on ne peut pas cast dans cette situation. Il faut remplacer la fonction stricmp et ne pas utiliser de char* pour les chaînes de comparaisons avec prEntry.szExeFile, bref avec tout ce qui utilise des WCHAR utilisez des WCHAR et des fonctions faites pour les gérer.
Remplacez char* name par un WCHAR *name, et remplacez stricmp par un fonction faite pour les wchar, par exemple wcscmp ( https://www.microsoft.com/en-us/download/details.aspx?id=55979 ) : "wcscmp and _mbscmp are wide-character and multibyte-character versions of strcmp. "
0
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 33
30 juin 2013 à 15:14
Wow merci pour l'explication je comprend mieux,

mais j'ai utiliser le même code dans une autre application "Console application" et sa marche parfaitement, c'est pour sa que je suis un peut déboussolé, la j'utilise une application Windows Form c'est la seul différence...
0
Hxyp Messages postés 401 Date d'inscription vendredi 28 janvier 2011 Statut Membre Dernière intervention 27 avril 2014 54
30 juin 2013 à 17:11
Hm peut-être qu'il y a moins de restrictions avec le compiler pour la console je veux dire que j'imagine qu'il y a peut-être un genre d'optimisation le wchar passe en char ? La console n'étant peut-être pas pour de l'unicode contrairement aux windows forms. Peut-être aussi que l'espace du tableau de wchar est utilisé comme un tableau de char. Ça fait beaucoup de "peut-être" car il y a pas mal de possibilités pour faire fonctionner la chose, mais ce dont vous pouvez être sûr c'est que c'est source de problèmes de mélanger wchar et char, ils n'ont pas la même taille et les données qu'ils vont contenir n'ont pas non plus le même type d'encodage, quand ça marche c'est de la chance ou alors on sait vraiment ce qu'on fait. Et si je me souviens bien il y a une préservation de l'ascii dans l'unicode ce qui fait qu'ils peuvent "passer" au mieux comparer à un char contenant de l'ascii lui aussi, mais l'alphabet latin n'est pas fait pour toutes les langues et donc ça plantera ou ne fonctionnera pas correctement avec d'autres langues leurs symbols seront sur 16bits la comparaison de 16bits contre 8bits ça ne fonctionne pas y a perte de données et n'est pas comparable à l'ascii contenu dans les 8bits d'un char donc source de problèmes. Je vous conseil de ne pas utiliser le char mais uniquement le wchar et les fonctions faites pour manipuler ce type ça vous évitera des soucis.
0
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 33
Modifié par jboss38 le 30/06/2013 à 17:56
Ok merci j'vais essayer de tout remplacer, a ouai mais nan enfaite si je remplacer par wchar* jvais avoir une erreur du coté de GetProcessID

error C2664: 'GetProcessID' : impossible de convertir le paramètre 1 de 'const char [8]' en 'wchar_t *'
1> Les types pointés n'ont aucun rapport entre eux ; conversion nécessitant reinterpret_cast, cast de style C ou cast de style fonction
0
Hxyp Messages postés 401 Date d'inscription vendredi 28 janvier 2011 Statut Membre Dernière intervention 27 avril 2014 54
Modifié par Hxyp le 30/06/2013 à 18:05
S'il dit "const char[8]" c'est qu'il y a du char quelque part, GetProcessID c'est vôtre fonction doit pas y avoir de problème à la modifier. Ça vient peut-être de son appel maintenant que j'y pense, avez vous fait un genre de :
char test[8]="hello";
GetProcessID(test);
après avoir remplacer les types char de la fonction ?
0
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 33
30 juin 2013 à 18:55
Non c'est bon le problème est résolu je vous invite a regarde juste en dessous
0
jboss38 Messages postés 829 Date d'inscription samedi 4 octobre 2008 Statut Membre Dernière intervention 14 décembre 2016 33
30 juin 2013 à 18:03
Aaaaaaaaaaaaahhhhhh

J'ai réfléchis et maintenant je me rappel que j'avais eu un problème de caractère en Unicode, je suis donc passez en multioctet pour résoudre le problème:

Il faut allez dans "Projet", puis allez dans Propriétés -> Propriétés de configuration -> Général -> Jeu de caractères, sélectionner le second choix à savoir, Utiliser le jeu de caractères multioctet.
0