IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Reconnaitre le type d'encodage d'une chaine de caractere


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut Reconnaitre le type d'encodage d'une chaine de caractere
    Bonjour,
    j'aimerais savoir s'il y a un moyen simple de reconnaitre le type d'encodage d'une chaine de caractere. Je m'explique, j'ai fais une DLL C++ avec une fonction qui re�oit une chaine de caractere :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    void __stdcall TestReception(LPWSTR Texte);
    seulement voila, certains programmes encodent leurs chaines de caracteres en UNICODE (PowerBuilder 10) et d'autre en ANSI (PowerBuilder 9), donc ma fonction ne marche pas partout. J'aimerais donc pouvoir reconnaitre le type d'encodage de ma chaine de caractere pour que le type de mon Texte corresponde.

    Sinon quelle demarche je devrais entreprendre ?

    Merci

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    G�n�ralement, pour les DLL, on utilise la m�me pratique que Windows:
    Fonction d�clar�e en extern "C", avec deux versions:
    TestReceptionA pour ansi
    TestReceptionW pour unicode

    Et le #define qui va avec, dans le header:
    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
    #ifdef __cplusplus
    extern "C" {
    #endif
    void __stdcall TestReception(LPTSTR Texte);
    void __stdcall TestReceptionA(LPSTR Texte);
    void __stdcall TestReceptionW(LPWSTR Texte);
    #ifdef __cplusplus
    }
    #endif
     
    #ifdef UNICODE
    #define TestReception TestReceptionW
    #else
    #define TestReception TestReceptionA
    #endif
    Ainsi, la fonction elle-m�me ne fait pas la diff�rence, mais l'appelant peut appeler deux fonctions s�par�es.

    Ensuite, si ta fonction n'a besoin que d'un seul code source, tu peux faire comme ceci (�a peut paraitre sale, mais �a marche):
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    // Fonction.cpp
    #include <windows.h>
     
    extern "C" void __stdcall TestReception(LPTSTR Texte)
    {
    //Faire quelque chose sur le texte avec les fonctions utilisant des TCHAR
    }
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    // FonctionU.cpp
    #define UNICODE
    #define _UNICODE
     
    //Compile les fonctions en version unicode
    #include "Fonction.cpp"




    Par contre, si tu veux une fonction qui doit reconnaitre d'elle-m�me l'encodage � partir d'un pointeur ind�termin�, essaie peut-�tre la fonction IsTextUnicode()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut
    Je n'arrive pas � mettre en place ta premiere m�thode, j'aurai 2-3 questions. Dans mon header, quelle fonction faut-il exporter ? les 3 ? ou juste la g�n�rale ? Pour l'instant j'ai fait comme �a :

    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
    #ifdef __cplusplus
    extern "C" {
    #endif
    EXPORT void __stdcall TestReception(LPTSTR Texte);
    void __stdcall TestReceptionA(LPSTR Texte);
    void __stdcall TestReceptionW(LPWSTR Texte);
    #ifdef __cplusplus
    }
    #endif
     
    #ifdef UNICODE
    #define TestReception TestReceptionW
    #else
    #define TestReception TestReceptionA
    #endif
    Ensuite dans le .cpp, il ne faut bien implementer que les 2 fonctions TestReceptionA(LPSTR Texte) et TestReceptionW(LPWSTR Texte) ou alors les 3 ? Mon cpp ressemble � �a :

    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
    void TestReceptionW(LPWSTR Texte)
    {
    	USES_CONVERSION;
     
    	ecrit_fichier("Entrée dans TestReceptionW");
     
    	AfxMessageBox(W2CA(Texte));
     
    	ecrit_fichier(to_string(Texte));
    }
     
    void TestReceptionA(LPSTR Texte)
    {
    	ecrit_fichier("Entrée dans TestReceptionA");
     
    	ecrit_fichier(to_string(Texte));
    }
    et lorsque je compile le tout j'obtiens ces 2 erreurs :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    error C2373: 'TestReceptionW' : redefinition; different type modifiers
    error C2373: 'TestReceptionA' : redefinition; different type modifiers
    Et pour finir, si j'exporte la fonction generale TestReception, c'est elle que j'appelle depuis l'ext�rieur et c'est la DLL qui m'envoit vers la bonne fonction en fonction du type de l'encodage ?

  4. #4
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Alors, je vais r�pondre � tes questions dans l'ordre:
    1�) Il faut exporter les deux (A et W).
    La d�claration de la fonction g�n�rale ne sert � rien pour le compilateur, en fait (mais elle peut servir � ton EDI, c'est pour cela que je l'avais mise). La fonction g�n�rale n'a pas d'impl�mentation (en tout cas, elle n'en a pas une fois le code compil�).

    2�) Comme je te l'ai dis, deux possibilit�s:
    • Soit tu impl�mentes les deux (A et W) s�par�ment (dans ce cas, tu n'as besoin que d'un seul fichier source),
    • Soit tu "impl�mentes" la fonction g�n�rale (en fait, c'est comme si tu faisais seulement semblant de l'impl�menter) en utilisant des TCHAR, et gr�ce aux #define et au second fichier source (mon "FonctionU.cpp"), elle sera compil�e deux fois: Une fois en A, l'autre en W
    G�n�ralement, on choisit entre ces deux solutions selon le degr� de diff�rence entre les deux versions. Des fois il est plus simple de faire avec une seule, des fois il est mieux de faire les deux s�par�ment.

    3�) Puisque tu dois exporter les deux, le programme ext�rieur doit appeler lui-m�me la bonne fonction.
    • S'il est �crit avec des TCHARs, il pourra utiliser la "fonction" g�n�rale: Gr�ce aux #define, l'appel sera transform� en un appel de la bonne fonction (si pas compil� avec UNICODE, il appellera explicitement TestReceptionA, si compil� avec UNICODE, il appellera explicitement TestReceptionW).
    • S'il est �crit avec des chars et des WCHARs, il faudra appeler explicitement l'une des deux fonctions dans le fichier source: Pour traiter une LPWSTR, appeler TestReceptionW, etc.

    PS: Pense � rajouter des gardes d'inclusion dans ton header: Il ne faut pas qu'il soit pass� deux fois, car � ce moment-l�, la fonction "g�n�rale" se retrouvera avec une double d�claration, ce qui peut (peut-�tre) �tre la cause de ton erreur.
    PS2: La cause de ton erreur, ce doit �tre que tu as oubli� les __stdcall dans l'impl�mentation. Ces modifieurs (ainsi que ceux pour l'exportation) doivent figurer dans la d�claration et la d�finition.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut
    tr�s juste pour les erreurs. Erreurs stupides d'inattention. Pour le reste j'essaye ...

  6. #6
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut
    Bon alors j'ai r�ussi � faire ce que je cherchais a faire avec la fonction IsTextUnicode(), c'est � dire tester dans ma fonction si le texte entr� en parametre est du texte unicode ou non et ensuite le traiter dans les 2 cas. Je met ma fonction pour ceux que �a interesse (du moins la m�thode) :

    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
     
    Dans le .cpp :
     
    // entrée en parametre le texte et la taille du texte
    void __stdcall TestReception(LPTSTR Texte, int taille)
    {
    	USES_CONVERSION;
     
    	if (IsTextUnicode(Texte,taille,(LPINT) NULL))
    	{
    		// le texte est du texte UNICODE
    		LPWSTR CopieTexte = (LPWSTR) Texte;
    		...
                    // ensuite on peux traiter le texte CopieTexte comme une chaine de caractere UNICODE
    	}
    	else
    	{
    		// le texte n'est pas du texte UNICODE
    		LPSTR CopieTexte =  (LPSTR) Texte;
    		...
                    // ensuite on peux traiter le texte CopieTexte comme une chaine de caractere NON UNICODE
    	}
    }
     
    Dans le .h :
     
    void __stdcall TestReception(LPTSTR Texte, int Taille);
    Par contre pour la m�thode avec les macros (que je n'ai finalement pas mise en place car elle ne semblait pas correspondre � mes attentes) j'aurai 1 question :

    tu as dis
    S'il est �crit avec des TCHARs, il pourra utiliser la "fonction" g�n�rale: Gr�ce aux #define, l'appel sera transform� en un appel de la bonne fonction (si pas compil� avec UNICODE, il appellera explicitement TestReceptionA, si compil� avec UNICODE, il appellera explicitement TestReceptionW).
    Dans ce cas ci, c'est par rapport � l'OS que la fonction sera compil� avec UNICODE ou pas ? Ou c'est la personne qui compile qui le d�cide ? Dans ce cas si c'est compil� avec UNICODE, si la fonction re�oit du texte non UNICODE elle ne marchera pas ? Si on me comprend et si j'ai bien compris, cette m�thode ne sert pas � faire ce que je voulais...

  7. #7
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Salut,
    1�) Si tu utilises IsTextUnicode, n'utilise pas un LPTSTR/LPCTSTR comme param�tre, mais un LPVOID: Le LPTSTR n'est pas un pointeur magique qui sait si le texte est d'un type ou non.
    Le LPTSTR, c'est toujours un LPSTR si le programme n'est pas compil� avec UNICODE, ou toujours un LPWSTR si le programme est compil� en UNICODE.

    2�) Celui qui d�cide, c'est l'utilisateur qui compile: sur un vieux compilateur, �a peut se d�cider en rajoutant des #define UNICODE et #define _UNICODE (il faut les deux, suite � une couille dans les en-t�tes) au d�but de chaque source, ou tout simplement en ligne de commande (-D UNICODE et -D _UNICODE pour gcc). Sur Visual 2005, il y a une option pour cela dans les propri�t�s du projet.

    Ainsi, si tu compiles avec UNICODE, tu auras ces d�finitions:
    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
    //Dans les headers Windows
    typedef WCHAR TCHAR, _TCHAR, *LPTSTR;
    typedef const WCHAR *LPCTSTR;
    #define TEXT(s) L##s
     
    #define CreateWindow CreateWindowW
    #define MessageBox MessageBoxW
    //etc.
     
    //-----------------------
    //Dans le header:
    void __stdcall TestReception(LPTSTR Texte);//Ici, LPTSTR équivaut à LPWSTR
    void __stdcall TestReceptionA(LPSTR Texte);
    void __stdcall TestReceptionW(LPWSTR Texte);
     
    #define TestReception TestReceptionW
    Ainsi, si dans le programme appelant, tu avais mis un:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    TCHAR texte[10] = TEXT("blabla");
    TestReception(texte)
    Une fois le programme appelant compil� en unicode, il correspondra �:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    WCHAR texte[10] = L"blabla";
    TestReceptionW(texte)
    Donc le programme appellera TestReceptionW.


    Ici, la fonction � appeler (A ou W) est choisie statiquement � la compilation. C'est ainsi que sont faits la plupart des programmes Windows, parce que les headers Windows sont fait exactment comme le header que j'ai montr�.
    Tandis que ta fonction utilisant un LPVOID (oui, j'ai dit un LPVOID) et IsTextUnicode choisira son traitement dynamiquement � l'ex�cution.
    Ici, tu as donc vraiment impl�ment� (sans faire semblant) une fonction g�n�rique qui choisit dynamiquement le traitement � effectuer.
    Il faut savoir que �a prend du temps de calcul et que c'est rarement utile. G�n�ralement, le choix statique suffit.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut
    Effectivement LPVOID �a semble plus logique, et marche tout aussi bien (surement mieux meme lol). Je savais ce qu'etait le LPTSTR mais �a marchait alors jme suis di allons bon.

    Bon sinon pour la m�thode statique, je pense avoir bien compris maintenant. Et �a confirme ce que je pensais � savoir qu'en faisant la m�thode statique, c'est repousser le probl�me au programme appelant la fonction. Parce que si on fait 2 fonctions, une W pour l'unicode et une A pour l'ansi, je devrais savoir qu'elle est le type d'encodage de mon texte dans mon programme appelant pour appeler la bonne fonction. Et en fait la finalit� de ma fonction C++ et qu'elle sera dans une DLL et susceptible d'etre appel�e par diff�rents programmes. Certains encodant leur texte en UNICODE (comme PowerBuilder 10 par exemple) et d'autre en ANSI (comme PowerBuilder 9 par exemple). Donc le faite de trouver dynamiquement le type d'encodage du texte me semble le plus judicieux, au d�triment de la rapidit� que je ne pense pas beaucoup amoindri.

    Merci pour ton aide pr�cieuse.

  9. #9
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Ben, la logique g�n�ralement utilis�e est la logique inverse: Comme le programme appelant, lui, sait comment il est cod� (ansi ou unicode), c'est � lui de savoir quelle fonction appeler, sans que la DLL ait � s'emm***er � deviner (surtout qu'elle peut se tromper: la doc dit bien que IsTextUnicode() n'est pas fiable � 100%; C'est vraiment de deviner que je parle).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    tsp
    tsp est d�connect�
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    82
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 82
    Par d�faut
    c'est vrai, bon ben je vais voir par la suite. thanks

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. tester le type de contenu d'une chaine
    Par thechris33 dans le forum VB.NET
    R�ponses: 7
    Dernier message: 11/06/2008, 22h11
  2. reconnaitre une chaine de caracteres
    Par inh40 dans le forum C++
    R�ponses: 4
    Dernier message: 10/04/2007, 11h21
  3. [VBA-Excel] reconnaitre une chaine de caractere
    Par DonKnacki dans le forum Macros et VBA Excel
    R�ponses: 2
    Dernier message: 13/06/2006, 16h15
  4. R�ponses: 3
    Dernier message: 01/08/2005, 12h15
  5. [D�butant]Encodage d'une chaine de caract�res
    Par Crazyblinkgirl dans le forum Entr�e/Sortie
    R�ponses: 3
    Dernier message: 03/08/2004, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo