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 :

Erreur de conversion de type entre c++ et l'api windows.


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut Erreur de conversion de type entre c++ et l'api windows.
    Bonjour à tous.

    Voici plusieurs jours que je me bats avec ces problèmes sans trouver de solution.

    Selon l'environnement de développement que j'utilise, j'ai un morceau de code qui tourne correctement dans certains ou qui génère des erreurs. Je n'arrive pas à me sorti de cette situation.

    Voici le morceau de code en question :

    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
     
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
     
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstring>
     
    typedef std::pair<std::string, std::string> NameValuePair;
     
    void
    loadIniFile( const std::string&          iniFilePath,
                 const std::string&          sectionName,
                 std::vector<NameValuePair>& nameValuePairs ) {
        const int bufferSize = 10000;
        char buffer[bufferSize] = "";
     
        int charsRead = 0;
     
        charsRead = GetPrivateProfileSection( sectionName.c_str(),  //_In_  LPCTSTR lpAppName
                                              buffer,                                  //_Out_ LPTSTR  lpReturnedString
                                              bufferSize,                            //_In_  DWORD   nSize
                                              iniFilePath.c_str() );               //_In_  LPCTSTR lpFileName
    Si j'utilise code::blocks ou éclipse CDT, ce code compile sans difficulté (les deux doivent utiliser GCC).

    Si j'utilise Qt (compilateur MinGW) j'obtiens cette erreur :

    erreur : cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}' for argument '1' to 'DWORD GetPrivateProfileSectionW(LPCWSTR, LPWSTR, DWORD, LPCWSTR)'
    iniFilePath.c_str() );//_In_ LPCTSTR lpFileName
    ^
    Avec MS Visual studio 2010 j'ai cette erreur aussi :

    error C2664: 'GetPrivateProfileSectionW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'

    Et enfin sur MS Visual Studio 2015 (compilateur Visual Studio 2015 - Visual C++ 19.0) j'ai plusieurs erreurs :


    Erreur (active) l'argument de type "const char *" est incompatible avec le paramètre de type "LPCWSTR" GetPrivateProfileSection c:\Users\Serge\Documents\Visual Studio 2015\Projects\GetPrivateProfileSection\GetPrivateProfileSection\GetPrivateProfileSection.cpp 27

    Erreur (active) l'argument de type "char *" est incompatible avec le paramètre de type "LPWSTR" GetPrivateProfileSection c:\Users\Serge\Documents\Visual Studio 2015\Projects\GetPrivateProfileSection\GetPrivateProfileSection\GetPrivateProfileSection.cpp 28

    Erreur (active) l'argument de type "const char *" est incompatible avec le paramètre de type "LPCWSTR" GetPrivateProfileSection c:\Users\Serge\Documents\Visual Studio 2015\Projects\GetPrivateProfileSection\GetPrivateProfileSection\GetPrivateProfileSection.cpp 30

    Erreur C2664 'DWORD GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR)'*: impossible de convertir l'argument 1 de 'const char *' en 'LPCWSTR' GetPrivateProfileSection c:\users\serge\documents\visual studio 2015\projects\getprivateprofilesection\getprivateprofilesection\getprivateprofilesection.cpp 30


    En synthèse j'aurais ces questions :

    1) Pourquoi ce code fonctionne-t-il correctement dans certains cas et pas dans d'autres ?

    2) Visiblement, il y a - à minima - une erreur de conversion : ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const std::string&          iniFilePath,
    ....
    iniFilePath.c_str() );//_In_  LPCTSTR lpFileName
    Comment correctement effectuer cette conversion ?

    3) VS2015 rajoute aussi 2 erreurs de compatibilité :

    en ligne 28
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	char buffer[bufferSize] = "";
    ...
    		buffer,               //_Out_ LPTSTR  lpReturnedString
    et en ligne 29

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	const int bufferSize = 10000;
    ...
    		bufferSize,           //_In_  DWORD   nSize
    Comment traiter aussi ces deux erreurs.

    Plus généralement peut-on trouver un tableau de conversion entre les types C++ et ceux de l'api windows ?

    Merci pour votre aide.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    LPCWSTR est un const wchar_t*.
    Tu peux utiliser std::wstring_convert pour convertir aisément.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Dans ton cas, la solution "Quick & Dirty" serait d'utiliser GetPrivateProfileStringA() au lieu de GetPrivateProfileString().

    Une meilleure solution serait d'utiliser des wstring partout et utiliser GetPrivaleProfileStringW().

    La solution optimale serait d'utiliser des basic_string<TCHAR>, généralement je fais ça avec un typedef:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef std::basic_string<TCHAR> tstring;
    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.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut
    merci à vous deux.

    @Bousk :
    J'ai quelques problèmes avec cette solution, d'autant que l'exemple donné dans le lien cplusplus.com ne compile pas chez moi. Et comme ma compréhension se construit en faisant tourner les programmes dans le débogueur, je n'ai pas réussi à l'implémenter.

    @Medinoc :
    La solution "quick & dirty" fonctionne très bien et ne cause pas de problème de compilation dans aucun IDE. C'est un grand progrès.

    La solution par les wstring, je ne vais, à priori, pas l'explorer (en tous cas pas maintenant).

    En revanche la solution basic_string<TCHAR> m'intéresse. Elle est déjà recommandée (mais malheureusement non implémentée) dans ce tuto http://sdz.tdct.org/sdz/apprentissag...i-windows.html qui débroussaille le sujet... et elle revient sur la proposition de Bousk (wchar_t ou char selon l'encodage). C'est donc la bonne pratique que je dois mettre en œuvre.

    Je vais donc m'appliquer à comprendre cette macro. Auriez-vous un "tip" supplémentaire pour m'orienter dans cette voie ?

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Sur le coup, je ne vois pas trop quoi dire, à part que:
    1. Tout va ensemble: Les fonctions Win32, les TCHAR, et la macro TEXT() (ou _T()) autour des chaînes littérales pour les déclarer comme étant des chaînes de TCHAR.
    2. Ça ne se marie pas toujours très bien avec les flux C++, selon l'IDE et sa version. Le problème principal est qu'il faut tout définir à la main (typedef basic_string<TCHAR> _tstring;, etc.) plutôt que se reposer sur des définitions fournies par l'IDE, car elles ne sont fournies que pour l'API Windows et les fonctions de la bibliothèque standard du C.
    3. Parfois, tu as besoin de passer de l'un à l'autre: Personnellement, j'aime bien des fonctions comme celles-ci (avec en plus, si besoin quelques #define pour récupérer ce qu'on veut en tant que chaîne de TCHAR:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      #ifdef UNICODE
      #define GetStringT GetStringW
      #else
      #define GetStringT GetStringA
      #endif
      )
    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/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par KonTiKI Voir le message
    J'ai quelques problèmes avec cette solution, d'autant que l'exemple donné dans le lien cplusplus.com ne compile pas chez moi. Et comme ma compréhension se construit en faisant tourner les programmes dans le débogueur, je n'ai pas réussi à l'implémenter.
    Et l'erreur est... ?
    Ma boule de crystal est en vacances.

    L'utilisation est plutôt simple, Google fournira bien plus d'exemples bien sûr.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::wstring to_string(const std::string& s) { std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; return converter.from_bytes(s); }
    std::string to_string(const std::wstring& s) { std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; return converter.to_bytes(s); }
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut
    Et l'erreur est... ?
    Ma boule de crystal est en vacances.
    Effectivement ... et pour tout dire la mienne aussi (et j'en aurai bien besoin)

    En fait deux erreurs de link dans VS :

    Erreur LNK2001 symbole externe non résolu "__declspec(dllimport) public: static class std::locale::id std::codecvt<char32_t,char,struct _Mbstatet>::id" (__imp_?id@?$codecvt@_UDU_Mbstatet@@@std@@2V0locale@2@A)

    qui reporte ici :
    https://msdn.microsoft.com/query/dev...001%29&rd=true

    et


    Erreur LNK1120 1 externes non résolus wstringconvert

    qui reporte ici :
    https://msdn.microsoft.com/query/dev...120%29&rd=true

    Autant dire qu'à ce niveau d'erreur le dépassement de mon seuil d'incompétence se calcule en années lumière.

    ############################

    Merci pour votre aide sur ce sujet, mais visiblement l'utilisation de l'API windows est trop difficile pour mon niveau.

    J'abandonne donc cette voie et retourne vers quelque-chose de plus conventionnel.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    mais visiblement l'utilisation de l'API windows est trop difficile pour mon niveau.
    Un peu de persévérance.

    En plus vous vous prenez un bug de VS2015 dans les dents, c'est pas de bols.
    http://stackoverflow.com/questions/3...-t-or-char32-t

    J'abandonne donc cette voie et retourne vers quelque-chose de plus conventionnel.
    L'API "Windows", en fait Win32 ici, c'est une API C CONVENTIONNEL.
    Si vous avez des difficultés avec cette API C, standard, vous en aurez partout, car le C est un peu l'espéranto de l'informatique.

    C'est, dans le fond, très simple.
    -> Dans une API C, vous devez utiliser les types C spécifiés dans les .h/documentation.
    https://msdn.microsoft.com/fr-fr/lib...or=-2147217396

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    DWORD WINAPI GetPrivateProfileSection(
      _In_  LPCTSTR lpAppName,
      _Out_ LPTSTR  lpReturnedString,
      _In_  DWORD   nSize,
      _In_  LPCTSTR lpFileName
    );
    C'est donc des LPTSTR et autres LPCTSTR qui sont demandées et pas des "const char *" et autre "char*".
    Avec des configurations particulières, et comme le C est pas très regardant avec le typage, on arrive à coller un peu n’importe quoi dans les paramètres, en faisant sauter pas mal de sécurité au passage.
    Mais plus les IDE sont perfectionnés, moins ces configurations particulières (et foireuses) sont les réglages par défauts.

    Les fonctions de @Médinoc (et les autres solutions proposées dans la discussion dont il donne l'URL) ont pour but de faire le transtypage automatiquement des types C++ vers ces LPTSTR et autres LPCTSTR.

    La solution de @Bousk semble avoir un problème avec VS2015 dû à un bug dans le compilateur, mais la solution de @Médinoc est simple à mettre en œuvre.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Etrange puisque nous utilisons VS2015 Update 3 et n'avons absolument aucun souci
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    Le dernier message du mainteneur de la STL dans VS date de Janvier 2016.
    Peut-être que l'Update 3, s'il date d'après Janvier 2016, a corrigé le problème.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut
    Merci pour cette information, bacelar.

    Donc si je résume, le code tournant sous Code::blocks (oui, je sais ) et éclipse serait bon et devrait s'adapter à VS si le bug était corrigé ?

    C'est, dans le fond, très simple.
    -> Dans une API C, vous devez utiliser les types C spécifiés dans les .h/documentation.
    J'ai effectivement vu des codes comme ceux-ci dans mes recherches. Faut-il pour cela une include particulière ou une instruction particulière pour le compilateur.

    Auriez-vous un simple exemple de cette fonction qui tourne dans un code C++ ?

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    le code tournant sous Code::blocks (oui, je sais ) et éclipse serait bon
    NON
    C'est :
    Avec des configurations particulières, et comme le C est pas très regardant avec le typage, on arrive à coller un peu n’importe quoi dans les paramètres, en faisant sauter pas mal de sécurité au passage.
    Donc non, sous Code::blocks (et éclipse?) , c'est tombé en marche parce que c'est truc tout moisi qui est encore, en 2016, en train d'utiliser réglages pour attaquer des API ASCII plutôt qu'UNICODE. (Putain 20/25ans de retard)

    C'est peut-être contre intuitif, mais c'est le code qui "fonctionne" sous Code::blocks qui est foireux, pas celui de @Bousk.

    Même si tu n'utilises pas le code de @Bousk, il est toujours conseillé d'avoir un compilateur à jour. Est-ce le cas ?

    Faut-il pour cela une include particulière ou une instruction particulière pour le compilateur.
    Juste "windows.h" devrait suffire.
    Il faut faire attention aux constantes de compilations, comme UNICODE ou WINVER etc..., qui changent les choses disponibles en fonction du type d'exécutable à générer, la plateforme cible, etc...

    Ici, c'est la constante de compilation UNICODE qui change le type des paramètres de "GetPrivateProfileSection".
    En utilisant des TCHAR, ton code reste valide quel que soit la valeur de la constante de compilation UNICODE.

    Cela peut sembler très complexe, mais il n'en est rien.
    Toutes les API Win32 qui supportent des chaines de caractères en entrée n'existent qu'en version UNICODE.
    Avant 1995, elles n'existaient quand version ASCII.
    Durant la transition, les OS supportaient, directement ou indirectement les 2 versions.
    Pour avoir du code qui fonctionne avec les anciens OS et aussi avec les futurs OS sans la version ASCII, on n'a sorti l'astuce du TCHAR.
    Cela permet d'avoir le même code pour tous les OS, qu'il ne supporte que l'ASCII (les vieux OS, très très vieux), ou qu'il ne supporte que l'UNICODE (les OS récents).

    Alors pourquoi la version ASCII fonctionne toujours ?
    Bin, elle ne fonctionne pas toujours, mais uniquement sur les vieux OS, et les OS qui ont des contraintes de compatibilités ascendantes fortes ( à la différence de feu WinCE par exemple) avec ces même OS.
    Pour ces OS avec contraintes fortes, le support est indirect, via une couche logicielle qui fait la conversion ASCII-->UNICODE.
    Donc, le jour où l'OS en aura mars de supporter de trucs d'il y a 30ans, plouf ça marchera plus.
    Donc, le jour où tu attaqueras un OS Windows type WinCE, plouf, ça marchera pas.
    On peut toujours créer un wrapper ASCII-->UNICODE "soi-même", et certaines chaines de compilation ont la leur, mais le jour où c'est plus supporté, plouf, ça marchera plus.

    Donc, pour éviter les ploufs, TCHAR est ton ami.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    199
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mars 2004
    Messages : 199
    Points : 103
    Points
    103
    Par défaut
    il est toujours conseillé d'avoir un compilateur à jour. Est-ce le cas ?
    Je le pense. J'utilise pour mon développement :
    - MS Visual Studio Update3
    - Qt Creator 5.7.0-mingw530

    Code::blocks et/ou éclipse CDT je ne les utilises que pour faire des tests rapides avec notepad++.

    Ici, c'est la constante de compilation UNICODE qui change le type des paramètres de "GetPrivateProfileSection".
    Oui, mais j'ai aussi fait un test (du code donné dans mon premier post) sous MSVS en passant le jeu de caractères de unicode à MBCS :
    En utilisant la fonction GetPrivateProfileSectionA, que le projet soit paramétré en Unicode ou en MBCS, il fonctionne. Si j'utilise la fonction GetPrivateProfileSectionW, il ne passe ni en paramétrage Unicode, ni en paramétrage MBCS. Or j'aurais pensé qu'en Unicode la fonction à utiliser est GetPrivateProfileSectionW alors qu'en MBCS la fonction est GetPrivateProfileSectionA. Visiblement, il n'en est rien.

    Mais si je comprends bien la différence ANSI / Unicode dans l'absolue (je me souviens bien de la programmation d'une imprimante matricielle avec les CP à utiliser sous DOS et win 3.0) je ne comprends pas le processus mis en œuvre et où intervient ce codage dans le workflow de la programmation aujourd'hui. Si l'API windows utilise de l'unicode, où dans mon code ai-je utilisé de l'ANSI ? C++ utilise-t-il de l'ANSI par défaut ? Et si je compile avec un paramétrage unicode pourquoi faut-il que je gère de l'ANSI ? bref, tout ceci n'est pas encore clair dans mon esprit. Quant au C, je n'en parle même pas, c'est la brasse coulée.

    Maintenant, si l'on ne vise que les OS actuels (je me fous de la compatibilité avec windows 95), la proposition de Medinoc d'utiliser GetPrivateProfileSectionA n'est-elle pas plus judicieuse que de passer par la macro TCHAR ?

    Merci en tous cas pour cette réponse explicite, qui m'a aussi bien faite sourire.

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le paramétrage du projet (Unicode/MBCS) ne change ni la version A d'une fonction, ni la version W.
    La seule chose qu'il change, c'est vers quelle version le #define sans suffixe pointe.

    En gros, les headers de Windows contiennent ceci (simplifié):
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #ifdef UNICODE
    	typedef wchar_t TCHAR;
    	#define TEXT(x) __TEXT(x)
    	#define __TEXT(x) L ## x
    	#define GetPrivateProfileString GetPrivateProfileStringW
    #else
    	typedef char TCHAR;
    	#define TEXT(x) x
    	#define GetPrivateProfileString GetPrivateProfileStringA
    #endif

    Les suffixes étant A pour "ANSI"* et W pour "Wide".

    Les strings de C++ utilisent des caractères étroits (alors que std::wstring utilise des caractères larges) et sous Windows, il n'est pas possible d'utiliser UTF-8 comme codepage par défaut, donc oui, sous Windows, "C++ utilise de l'ANSI par défaut".

    *En fait, la codepage 1252 n'a jamais été normalisée par l'ANSI, en fait dans le contexte de Windows "ANSI" signifie "caractères étroits utilisés dans les fenêtres", par opposition à "Wide" (caractères larges) et à "OEM" (qui signifie "caractères étroits utilisés dans les consoles).
    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.

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 073
    Points : 12 119
    Points
    12 119
    Par défaut
    Maintenant, si l'on ne vise que les OS actuels (je me fous de la compatibilité avec windows 95), la proposition de Medinoc d'utiliser GetPrivateProfileSectionA n'est-elle pas plus judicieuse que de passer par la macro TCHAR ?
    Bin non, si on vise que les OS actuels, on n'utilise que la version Wide. Mais pour cela, il faut que les chaines de caractères soient "wide", donc std::wstring à la place de std::string et préfixer les constantes par la MACRO "L".
    Mais quitte à faire tout ça, autant utiliser tstring et "T" ou "TEXT" pour que ça marche en Wide et en "ASCII".

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Sans compter que ça facilitera grandement la migration si jamais une version UTF-8 des fonctions voit le jour.
    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.

Discussions similaires

  1. erreur de conversion de type de donnée
    Par sunwind dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 05/05/2008, 10h44
  2. Réponses: 2
    Dernier message: 05/06/2007, 23h07
  3. Erreur 3421, Erreur de conversion de type de données
    Par khorn dans le forum VBA Access
    Réponses: 13
    Dernier message: 01/06/2007, 10h52
  4. [VB.Net] Erreur de conversion de type
    Par Khalid.bounouader dans le forum Accès aux données
    Réponses: 6
    Dernier message: 13/11/2006, 21h57
  5. Erreur de conversion de type Null en String
    Par navis84 dans le forum Bases de données
    Réponses: 3
    Dernier message: 26/07/2005, 15h25

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