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

Qt Discussion :

char*, QString et QStringList


Sujet :

Qt

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut char*, QString et QStringList
    Bonjour,

    Je reçois un char* d'une dll externe, contenant une liste de noms séparés par des NULL et terminée par double NULL.
    J'ai utilisé un code trouvé sur internet sur cette dll qui remplace les NULL par des vigules puis place les mots dans un vecteur. J'ai remplacé cette dernière partie par le remplissage d'une QStringList.
    Cette QStrinList est ensuite utilisée pour paramétrer un programme lancé par un QProcess.
    Ce programme renvoie une erreur mais affiche bien les bons paramètres.
    Si je lance ce programme directement en ligne de commande avec les mêmes paramètres il fonctionne sans erreur.
    Si dans mon code j'alimente la liste en dur (<<) avec des noms, le programme fonctionne pour ces noms mais toujours pas pour les autres.

    Je pense qu'il 'a un problème dans l'alimentation de ma liste, mais comme les bons noms sont affichés dans mes sorties de debuggage il s'agit peut-être d'un problème de "code page".
    Comment le résoudre ?
    Puis-je créer simplement ma liste directement avec des fonctions Qt ?

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Ca doit être faisable. Peux tu nous montrer un bout de code, et un screenshot de l'erreur que ton programme renvoit ?

    G.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (...)
                convertToCsv(s__info.jobList);
     
                char sep[] = ",";
                QStringList jobs;
                char* token = strtok(s__info.jobList,sep);
                while (token != NULL) {
                        jobs << QString(token).trimmed();
                        token = strtok(NULL,sep);
                }
    (...)
    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
    char* convertToCsv(char* strArray) {
     
            char* ptr = strArray;
            size_t len;
     
            if (strArray != NULL) {
                    //while (ptr[0] != NULL) {
                    while (ptr[0] != '\0') {
                            len = strlen(ptr);
                            //if (ptr[len+1] != NULL) {
                            if (ptr[len+1] != '\0') {
                                    ptr[len] = ',';
                            }
                            ptr += len+1;
                    }
            }
            return strArray;
     
    }
    Le message d'erreur du sous-programme renvoie bien le nom "test02" mais n'a pu effectuer le traitement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Processing "test02" - Failed
    Cannot get exclusive access to executable file for job test02
    Si je fais dans mon code jobs << "test02" j'ai bien en plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Intializing
     
    Processing "test02" - Succeeded

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Et un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    convertToCsv(s__info.jobList);
    QString jobList(s__info.jobList);
    QStringList jobs = jobList.split(",");
    qDebug()<<jobs;
    G.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour DSGSLA

    J'ai testé ton code et j'ai comparé avec un code "maison" :

    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
    char array[9] = { 'A', 'B', '\0', 'C', 'D', '\0', 'E', '\0', '\0' };
    QString str;
    bool continu = true;
    char last = '\1';
    char * ptr = array;
     
    while(continu)
    {
        if((*ptr) == '\0')
        {
            if(last == '\0')
            {
                continu = false;
            }
            else
            {
                list << str;
                str = QString();
            }
        }
        else
        {
            str += (*ptr);
        }
        last = *ptr;
        ++ptr;
    }
    Ton code fonctionne correctement et retourne le résultat attendu (testé sur la chaine de caractères indiquée dans le code)

    Le problème provient peut être de ton appel à QProccess. Tu peux nous montrer ton code d'appel ?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    J'ai trouvé : ce n'est pas la constitution de la liste mais le code ci-dessous (positionné après celui déjà montré) qui agit je ne sais comment sur la QStringList et qu'après ça foire.
    Mis en commentaire tout passe.
    La variable "force" prend la valeur 'O' ou 'N'.

    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
    28
    29
    30
    31
    32
    string status;
                int retval;
                for (QStringList::iterator it=jobs.begin(); it!=jobs.end(); it++) {
     
                        hJob = __OpenJob(hProject,(char *)it->toStdString().c_str());
                        if (hJob != NULL) {
                                err = __GetInfo(hJob,__JOBSTATUS,&s__Info);
                                if (err != __NOERROR) {
                                        retval = __NOTRUNNABLE;
                                } else {
                                        retval = s__info.jobStatus;
                                }
                        } else {
                                retval = __NOTRUNNABLE;
                        }
                        if (*force == 'N') {
                            if (retval != __NOTRUNNABLE ) {
                                getJobStatus(retval,status);
                                cout << "Job " << it->toStdString() << " deja traite (" << status << ")." << endl;
                            }
                        }
                        else {
                            if (retval == __RUNNING) {
                                cout << "Job " << it->toStdString() << " en RUNNING." << endl;
                                jobs.erase(it);
                            }
                            else {
                                getJobStatus(retval,status);
                                cout << it->toStdString() << "," << retval << "," << status << endl;
                            }
                        }
                }

    Peut-être que l'appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (char *)it->toStdString().c_str()
    modifie le contenu de la liste.

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    La conversion de QString en char* pose parfois quelques problèmes (en particulier à cause de l'UTF8 et l'internationnalisation). Il existe d'ailleurs plusieurs fonctions qui font des "choses" très proches mais très différentes quand même (toAscii(), toLatin1(), toUtf8(), toLocal8Bit()).

    Pour travailler avec le C, je te conseille la macro "qPrintable" de qtglobal.h qui est faite spécialement pour ça (http://qt.developpez.com/doc/4.6/qtglobal/#qprintable)

    PS : pour parcourir ta QStringList, tu peux utiliser aussi la macro "foreach" (http://qt.developpez.com/doc/4.6/qtglobal/#foreach) sans que cela soit très important pour les performances :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    foreach(QString str, TaStringList)
        ...

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    qPrintable renvoie un const char* et j'ai besoin d'un char*, le compilateur ne laisse pas passer ça.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Tu peux utiliser une conversion bourrin avec const_cast...

    EDIT : tu peux aussi faire str.tolocal8bit().data().

  10. #10
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Si tu lis la doc, il est indiqué :
    Returns str as a const char *. This is equivalent to str.toLocal8Bit().constData()
    il suffit alors d'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* str.toLocal8Bit().data();

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    Je vais devenir zinzin. Le simple fait de parcourir la liste après sa constitution et le sous-programme ne fonctionne plus ! Tant que j'envoie la liste sans y accéder ça marche !

  12. #12
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Le seul endroit où il pourrait y avoir un problème (à mon avis) est dans la fonction __OpenJob (étrange comme nom de fonction. C'est une lib ?)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    hJob = __OpenJob(hProject, (char *) it->toStdString().c_str());
    1. tu transformes un const char* en char*
    2. si ta fonction accède et modifie la taille de tes chaines, ça risque de planter (je ne sais pas comment QByteArray gère cela)

    Si tu commentes cette ligne, as-tu encore une erreur ?
    A quoi sert cette fonction ? Si c'est une fonction que tu as crées, pourquoi ne pas continuer à travailler avec QString ?

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Par défaut
    J'ai trouvé, ça n'avait rien à voir avec Qt, ou le C++.
    Après une des fonctions de la dll externe il faut appeler une fonction de "libération", sinon l'objet appelé par la dll reste verrouillé, ce qui plante le sous-programme.

    Merci quand même pour vos réponses.

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

Discussions similaires

  1. Convertir char vers QString
    Par darkwall_37 dans le forum Débuter
    Réponses: 3
    Dernier message: 25/05/2009, 11h49
  2. Passage d'un QString à un char* !
    Par atomicJo dans le forum Qt
    Réponses: 16
    Dernier message: 05/03/2009, 14h49
  3. Conversions implicites de QString en const char*
    Par mister3957 dans le forum C++
    Réponses: 3
    Dernier message: 22/08/2008, 17h27
  4. Conversion QString en char*
    Par Stage2006 dans le forum Qt
    Réponses: 5
    Dernier message: 12/06/2007, 17h14

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