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

Visual C++ Discussion :

Conversion unicode (utf-8)


Sujet :

Visual C++

Vue hybride

spender Conversion unicode (utf-8) 04/02/2009, 09h08
Médinoc Je ne connais pas trop... 04/02/2009, 11h42
spender Bonjour, Merci Médinoc... 04/02/2009, 11h58
Médinoc Pour faire une conversion, il... 04/02/2009, 12h19
Médinoc Pour la conversion vers... 04/02/2009, 12h23
ram-0000 J'avais optimisé un peu la... 04/02/2009, 12h32
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 82
    Par défaut Conversion unicode (utf-8)
    Bonjour,
    Je m'attaque au portage d'un application existante vers Unicode.
    Je suis sous Visual C++ Embedded 4 et j'ai bien la propriété unicode dans les settings du projet.
    Actuellement, j'ai un CEdit, je récupère son contenu que je met dans un char* puis je l'envoi à une autre appli via une socket. Ensuite, dans l'autre sens, je reçois un char* via une socket puis je l'affiche dans un CEdit. Le but désormais est d'échanger de l'unicode (format utf-8) avec cette seconde appli.
    Comment (avec quel type et méthode) puis-je passer du contenu du CEdit à un char* en passant par un encodage utf-8 et vice versa ?
    Merci d'avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Je ne connais pas trop Embedded, mais traditionnellement sous Windows on utilise les fonctions libres MultiByteToWideChar() et WideCharToMultiByte() avec le paramètre CP_UTF8.

    J'ignore s'il y a plus évolué sous MFC, ni ce que permet ta version de MFC. Dans cette version, CString est-elle une classe ou y a-t-il le template CStringT?
    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
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 82
    Par défaut
    Bonjour,

    Merci Médinoc pour la réponse.

    Je ne pense pas que CStringT, CStringA ou CStringW soient disponibles car ça a été implémenté après VC++ 6 d'après ce que dit la faq et là moi je suis sur une base de 4....
    Je me suis en effet tourné vers les méthodes MultiByteToWideChar() et WideCharToMultiByte() mais elles sont délicates à utiliser et je ne m'en sors pas pour le moment avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    LPWSTR orgUnicode = L"Coucou";
    LPSTR destUTF8 = NULL;
    //Unicode vers UTF-8
    WideCharToMultiByte(CP_UTF8, 0, orgUnicode, 6, destUTF8, 7, NULL, NULL); 
     
    orgUnicode = L"";
     
    //UTF-8 vers Unicode
    MultiByteToWideChar(CP_ACP, 0, destUTF8, 7, orgUnicode, 7); //wcslen(orgUnicode));
    Une idée de ce qui pourrait clocher ?

    Merci d'avance pour votre aide.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Pour faire une conversion, il faut deux appels à la même fonction:
    • Un avec un buffer nul, pour connaître la taille de buffer à allouer,
    • Et un avec un buffer fraichement alloué avec la bonne taille.
    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
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Pour la conversion vers Unicode, je m'étais fait cette fonction. Elle est plus compliquée que le strict nécessaire, mais elle est en C, retourne un HRESULT cas d'erreur et donne la taille de la chaîne en cas de succès:
    Code C : 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
    /* Get a HRESULT from a Win32 error code, or E_UNEXPECTED */
    static HRESULT GetHResultFromWin32(DWORD error)
    {
    	HRESULT hr = HRESULT_FROM_WIN32(error);
    	if(SUCCEEDED(hr))
    		hr = E_UNEXPECTED;
    	return hr;
    }
     
    /* Convert a char string into an unicode string. */
    HRESULT GetUnicodeString(
     LPCSTR sczInA,    /*[in] char string.*/
     UINT codePage,    /*[in] Code page identifier, or CP_ACP etc.*/
     LPWSTR * pSzOutW, /*[out] Receives a pointer to the new wide character string.*/
     int * pCchWritten /*[out/opt] If set, receives the length of the wide character string, in characters. */
     )
    {
    	HRESULT hrRet = E_UNEXPECTED;
    	int cchSizeW = 0;
     
    	/*Initialize optional output parameters to their default values*/
    	if(pCchWritten != NULL)
    		*pCchWritten = 0;
    	/*Test other output parameters, and initialize to their default values as long as possible*/
    	if(pSzOutW==NULL)
    		return E_POINTER;
    	*pSzOutW = NULL;
     
    	/*Test input parameters*/
    	if(sczInA==NULL)
    		return E_INVALIDARG;
     
    	/*Calculate size*/
    	cchSizeW = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, NULL, 0);
    	if(cchSizeW <= 0)
    		hrRet = GetHResultFromWin32(GetLastError());
    	else
    	{
    		/*Alloc buffer*/
    		LPWSTR szOutW = malloc(cchSizeW * sizeof *szOutW);
    		if(szOutW==NULL)
    			hrRet = E_OUTOFMEMORY;
    		else
    		{
    			/*Use buffer*/
    			BOOL bKeepMem = FALSE;
    			int cchWritten = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, sczInA, -1, szOutW, cchSizeW);
    			if(cchWritten <= 0)
    				hrRet = GetHResultFromWin32(GetLastError()); /*This error is very unlikely to happen, since it was tested before*/
    			else
    			{
    				/*OK!*/
    				hrRet = S_OK;
    				bKeepMem = TRUE;
    				*pSzOutW = szOutW;
    				if(pCchWritten!=NULL)
    					*pCchWritten = cchWritten;
    			}
     
    			if(!bKeepMem)
    				free(szOutW);
    		}
    	}
    	return hrRet;
    }
     
    /* Delete a wide character string allocated by GetUnicodeString() */
    HRESULT FreeUnicodeString(LPWSTR szDelW)
    {
    	if(szDelW==NULL)
    		return S_FALSE;
    	free(szDelW);
    	return S_OK;
    }
    J'ai aussi en stock une version de cette fonction qui donne une BSTR à la place.
    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.

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pour faire une conversion, il faut deux appels à la même fonction:
    • Un avec un buffer nul, pour connaître la taille de buffer à allouer,
    • Et un avec un buffer fraichement alloué avec la bonne taille.
    J'avais optimisé un peu la chose.

    Le premier appel, je donnais un buffer dont la taille était arbitraire (32 caractères), et je traitais les cas d'erreur. En cas d'erreur "buffer pas assez grand", je réallouais à la taille demandée et je faisais le deuxième appel.

    J'ai remarqué que dans la majorité des cas, j'économisais ainsi 1 appel.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 82
    Par défaut
    Bonjour,

    Merci Médinoc et ram-0000 pour vos réponses.
    Je vais donc tester la méthode du double appels successifs et vous tiendrai informé du résultat.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Conversions Unicode Ascii
    Par Klaim dans le forum C++
    Réponses: 25
    Dernier message: 01/08/2007, 22h15
  2. conversion iso -> utf
    Par troumad dans le forum C
    Réponses: 6
    Dernier message: 20/04/2007, 16h52
  3. Conversion vers UTF-8
    Par magnus2005 dans le forum Langage
    Réponses: 1
    Dernier message: 26/10/2005, 10h12
  4. Problème de conversion unicode
    Par djmalo dans le forum C
    Réponses: 5
    Dernier message: 09/03/2004, 11h48
  5. conversion Unicode -> ASCII
    Par juzam dans le forum C
    Réponses: 8
    Dernier message: 24/07/2003, 10h07

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