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 :

Comment initialiser une chaîne Unicode et y accéder avec son pointeur (LPWCSTR)


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Novembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 17
    Par défaut Comment initialiser une chaîne Unicode et y accéder avec son pointeur (LPWCSTR)
    Bonjour

    Ma question est une question de débutant à laquelle je n'ai pas trouvé de réponse évidente (même dans les FAQ)
    Petite précision j’utilise Visual C++ 6.0.

    Donc, j'ai besoin d'utiliser la fonction suivante qui renvoie un long :
    CeRegOpenKeyEx (HKEY, LPCWSTR, DWORD, REGSAM, PHKEY)

    Mon 2eme argument est un pointeur sur une chaîne constante en UNICODE. Dans mon cas cette chaîne contient le mot "Ident"

    Question, comment définir ma chaîne et son pointeur ? Y'a-t-il une façon simple et rapide (avec une macro). A priori je dirais qu'oui tellement cette opération est banale.

    Merci à tous de vos réponses.

    LS

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Attention, c'est un pointeur sur chaine ou une chaine?

    Il y a quatre cas: un char**, un const char **, un char* ou un const char *?

    • const char*, donne directement "Ident", c'est un littéral de type const char*
    • char*: il faut donner de la mémoire modifiable, je ne pense pas que ce soit demandé par la fonction. (déclarer char p[100], donner p)
    • char**: déclare un char *p, et donne &p a la fonction.
    • const char**: meme chose, mais en constant.



    Nul besoin de macro ici. Rappelle-toi qu'une macro est remplacé par le code correspondant dans le code. Il n'y a aucune magie créant de la performance.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Novembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 17
    Par défaut
    Bonjour l'Eternel

    Effectivement je suis bien d'accord la performance n'a rien de magique elle n'est que le fruit de la pratique...

    Dans mon cas la fonction attend un pointeur long (LP) sur une chaîne (STR) de longueur constante (C) dont chaque caractère tient sur 2 octets (W) puisque c'est de l'UNICODE.
    D’après mes connaissances en C++, il suffirait de déclarer un chaîne constante (const char []="Ident") de l'initialiser, de créer un pointeur sur cette chaîne et de l'initialiser avec l'opérateur &
    Le problème c'est que le type char n'est que sur un octet.

    Je vais essayer ce que tu me proposes donc a priori const char**. Au fait pourquoi const char**, et pas const char* ? Un pointeur sur un pointeur ? Je ne comprend pas bien cette syntaxe.

    En tous cas merci de ta précieuse aide.

    Bon dimanche.

    LS

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Tu as en C++ des wchar qui, je crois, se déclarent avec L"blabla".

    Cependant, tu es dans l'API de windows, que je ne connais pas.
    Tu as certainement un typedef à utiliser dans ce cas-là.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Je suis surpris, CeRegOpenKeyEx() demande explicitement une LPCWSTR et non pas une LPCTSTR comme la version Desktop.

    Le plus simple pour ça, c'est LPCWSTR keyName = L"Ident";.
    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
    Membre averti
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Novembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 17
    Par défaut Ca maaaaaaaaaarche !
    Bonjour Medinoc et Leternel

    Ca marche ! Plus d'erreur à la compil avec un simple "LPCWSTR keyName = L"Ident"

    Effectivement notre LPCWSTR est bien issu d'un typdef a base de wchar_t déclaré dans winnt.h. Au passage, comment mon projet sait qu'il doit intégrer ce .h ?
    typedef wchar_t WCHAR; // wc, 16-bit UNICODE character et quelques lignes plus bas typedef CONST WCHAR *LPCWSTR, *PCWSTR;Ce qui me gène c'est de ne pas trop comprendre comment et pourquoi ça marche !

    Y-a-t-il quelque-part un bon tuto sur ce L avant mon litteral.

    Merci de vos réponses. On se sent moins seul face au clavier !

    Bonne soirée et encore merci.

    PS:
    Vu le projet sur lequel je travail ce ne sera surement pas mon dernier message sur ce forum....

  7. #7
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    Bonsoir.

    Citation Envoyé par serral Voir le message
    Au passage, comment mon projet sait qu'il doit intégrer ce .h ?
    Les header inclus généralement d'autres header en cascade. À un moment, l'un d'entre eux a inclus winnt.h.

    Citation Envoyé par serral Voir le message
    Ce qui me gène c'est de ne pas trop comprendre comment et pourquoi ça marche !
    Dans cette utilisation typedef créé un « synonyme » ou un « alias » de type. Donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef wchar_t WCHAR; //WCHAR = wchar_t
    typedef CONST WCHAR *LPCWSTR, *PCWSTR; //LPCWSTR et PCWSTR = const WCHAR*, donc const wchar_t*.
    Citation Envoyé par serral Voir le message
    Y-a-t-il quelque-part un bon tuto sur ce L avant mon litteral.
    Ce "L" est un préfixe. Son rôle est de définir le type des constantes littérales. "Bonjour" est considéré comme un const char *, mais si on rajoute un L devant (L"Bonjour"), ça sera considéré comme un const wchar_t *, lui même synonyme de LPCWSTR comme vu avant.
    Il se passe la même chose en suffixant les nombres à virgule : 1.0 est un double, 1.0f est un float et 1.0L est un long double.

  8. #8
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Comme ton problème est résolu, pense à le marqué résolu (via le bouton en bas de la réponse)

  9. #9
    Membre averti
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Novembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 17
    Par défaut OK mais.....
    Bonjour et merci infiniment à Manudiclemente pour ces explications

    Néanmoins j'ai une petite question.
    Le "L", devant ma chaîne n'est-il pas redondant avec le LPCWSTR qu'on met avant et qui déjà en dit long sur ce qui suit.
    Idem pour un "float" auquel on rajoute un f. Puisqu'on declare "float nbr=1.2f"

    Merci de vos reponses.

    Cordialement.

    LS

  10. #10
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    Citation Envoyé par serral Voir le message
    Le "L", devant ma chaîne n'est-il pas redondant avec le LPCWSTR qu'on met avant et qui déjà en dit long sur ce qui suit.
    Non car un wchar_t* n'est pas transtypable en char*. wchar_t* w = "Bonjour"; sortira un erreur comme « cannot cast char* to wchar_t*);

    Citation Envoyé par serral Voir le message
    Idem pour un "float" auquel on rajoute un f. Puisqu'on declare "float nbr=1.2f"
    Ce f là est redondant, en général on ne le met pas.
    Par contre, le compilateur sait convertir un float en double, et un double en float (avec un warning « perte de précision » dans ce cas, puisqu'un double est plus précis qu'un float). Donc double d = 1.0f; compile, float d = 1.0; lance un warning.

  11. #11
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Il faut bien comprendre que chaque littéral a un type précis.
    • un nombre entier commencant par le chiffre 0 est octal
    • un nombre avec un . mais sans préfixe est un float.
    • un nombre avec un . et le préfixe L est un double.
    • une chaine sans préfixe est de type const char*
    • une chaine préfixée avec L est un const wchar_t*


    Il y en a d'autres, pour l'hexadécimal (0x, je crois), pour les caractères (comme les chaines), l'absence de signe (U), etc.

    Certains types se convertissent, certains avec warning, d'autres pas du tout.
    En cas de warning sur une conversion quand on a un littéral, il faut chercher le préfixe du type qu'on veut, ou changer le type de la variable.
    Il ne faut pas introduire le cast suggéré par le compilateur. Cette conversion est valable pour l'affectation depuis une variable

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Octal et hexadécimal sont des formats, non des types. Mais ils impliquent peut-être qu'un nombre est non-signé, je ne sais plus.
    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.

  13. #13
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Certes, mais ce sont des subtilités à connaitre.

  14. #14
    Membre averti
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Novembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2012
    Messages : 17
    Par défaut C'est clair !
    Bonsoir et merci pour toutes vos précisions.

    J'crois qu'j'ai tout compris.

    En fait il convient d'informer le compilateur du type de variable à initialiser quand la façon de l'écrire laisse planer le doute.
    "bonjour" en char* ressemble beaucoup à "bonjour" en wchar_t* d'où le "L".

    Ceci dit, on peut tout de même se demander pourquoi le compilateur ne déduit pas automatiquement que ce qu'il y a de l'autre coté du "=" est en rapport avec le typage de la constante. Autrement dit, si j'ai un pointeur sur un wchar_t d'un coté, il est assez logique de trouver un wchar_t en valeur d'initialisation. Bon enfin c'est comme ça.

    Merci à tous de vos réponses.

    LS

  15. #15
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    il est beaucoup plus efficace, en fait, d'avoir une convention de typage des littéraux qui soit uniforme.
    Il suffit juste de le savoir.

    Par ailleurs, ca rend plus homogène le fonctionnement de l'affectation.

    Dans wchar_t* var = other; la valeur de other est convertie avant d'être copiée dans var. Dans wchar_t* var = "truc"; c'est pareil.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/12/2009, 11h57
  2. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46
  3. Comment initialiser une ChildFrame ???
    Par loupdeau dans le forum MFC
    Réponses: 14
    Dernier message: 22/03/2005, 13h28
  4. Réponses: 5
    Dernier message: 15/02/2005, 18h07
  5. Réponses: 3
    Dernier message: 28/09/2003, 10h46

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