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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    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
    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 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    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
    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
    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 confirmé
    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
    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
    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
    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 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    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 confirmé
    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
    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.

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