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

Discussion :

Conversion entre QString et pj_str_t

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut Conversion entre QString et pj_str_t
    Bonjour à tous,

    j'utilise Qt pour le gui de mon application SIP. Pour traiter SIP, j'utilise le framework pjsip 2.1. Je suis souvent confronté au problème de conversion de chaine de caractères. En effet je récupère les données de mon formulaire Qt sous forme d'un QString et je dois le convertir en pj_str_t pour le passer au framework pjsip. Voici actuellement comment je fais pour passer de QString à pj_str_t

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    QString mystring = m_qtField.text();       
    QByteArray ba = mystring.toLatin1();      
     
    m_pj_account_cfg.username = pj_str(ba.data()); //ceci fonctionne
    Ce code fonctionne mais comme je dois le faire de nombreuse fois, je me suis dis que j'allai créer un classe pjsipQtWrapper qui va contenir des fonctions pour ce genre de conversion. Je crée donc une fonction comme ceci :

    pjsipqtwrapper.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class PjsipQtWrapper
    {
    public:
        static pj_str_t ToPj_str(QString *string);
    };
    pjsipqtwrapper.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "pjsipqtwrapper.h"
     
    pj_str_t PjsipQtWrapper::ToPj_str(QString *string)
    {
        QByteArray ba = QByteArray();
        ba = string->toLatin1();
        return pj_str(ba.data());
    }
    Lorsque que j'utilise ce code et que je print les valeurs à différents endroit comme par exemple dans la fonction, juste après la fonction etc. je vois des valeur correctes, mais lorsque que je l'assigne à un champs de structure pjsip, j'obtient des erreurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    m_pj_account_cfg.id = PjsipQtWrapper::ToPj_str(&mystring); //ne fonctionne pas
     
    pj_str username_p = PjsipQtWrapper::ToPj_str(&mystring);
    m_pj_account_cfg.id = username_p; //ne fonctionne pas
    Je n'ai vraiment aucune, mais aucune idée de mon erreur.

    merci d'avance de votre aide.
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  2. #2
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 619
    Points : 188 605
    Points
    188 605
    Par défaut


    Ça pourrait être utile de mettre les messages d'erreur .

    Au fait, pourquoi prendre un pointeur en paramètre ? Tu prends le risque qu'il soit nul à un moment ; si tu utilises une référence, elle sera toujours valide (dans le code machine généré, pas de différence notable avec les pointeurs).
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    Salut et merci de ta réponse. Ben il n'y a pas vraiment de message d'erreur mis à part celui généré par la librairie pjsip qui me dit que le mon URI est invalide (car je cherche a attribuer une valeur a un champ pj_str_t qui est l'uri d'un serveur SIP).

    Tu as raison je ne sais pas pourquoi j'ai utilisé le pointeur. Je vais modifier la définition de ma fonction comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static pj_str_t ToPj_str(QString& string);
    j'espère que le problème venait de là.
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    Alors après test, j'ai toujours le même problème. et voici l'erreur mais sa ne va pas aider.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    01:48:54.759    pjsua_acc.c  .Invalid local URI: Invalid URI (PJSIP_EINVALIDURI) [status=171039]
    01:48:54.759    pjsua_acc.c  .Error adding account: Invalid URI (PJSIP_EINVALIDURI) [status=171039]
    Je ne comprend vraiment rien
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    La première idée qui me viendrait à l'esprit, c'est que tu n'utilises pas le bon charset pour la donnée.

    Autrement dit, je subodore (mais je n'ai pas vraiment fouillé) que ton problème vient de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QByteArray ba = mystring.toLatin1();
    Cette page semble d'ailleurs me donner raison : pj_str_t manipule un char *.

    Tu devrais donc plutot utiliser toStdString, qui te renverra une std::string "classique", au départ de laquelle tu pourras récupérer une chaine C style normale

    Je prend un chemin détourné, je le sais, car il existe la fonction toAscii, mais, comme elle est marquée comme étant dépréciée...

    L'idée générale serait donc d'envisager un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_pj_account_cfg.username = pj_str(myString.toStdString().c_str());
    Il faut cependant être particulièrement prudent en agissant de la sorte, car le pointeur renvoyé par c_str() est réputé constant (tu ne peux en aucun cas envisager d'en modifier le contenu), et qu'il risque d'être modifié à chaque modification de la chaine de caractères (il ne lui survit d'ailleurs pas quand elle est détruite)

    Il est donc peut être "de bon ton" de veiller à créer une copie en profondeur (un new char[size], suivi d'un strcpy ou autre), afin de s'assurer que pjsip puisse en profiter "à sa guise"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    Merci beaucoup koala01,

    j'ai fais une fonction statique comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pj_str_t tools::toPjStr(QString &string)
    {
        const char* c = string.toStdString().c_str();
        char* s = new char[string.size()];
        strcpy(s, c);
     
        return pj_str(s);
    }
    et tout ceci semble fonctionner.
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Bon, maintenant, il faudrait juste vérifier deux choses:

    La bibliothèque semble être écrite en C, il vaudrait donc mieux utiliser malloc (car, si la bibliothèque utilise free pour libérer la mémoire... )

    Il faudrait aussi s'assurer que la bibliothèque se charge elle-même de libérer la mémoire pour cette chaine de caractères
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    J'ai effectivement des crashs de temps en temps. Penses-tu que cela puisse venir ce problème d'allocation justement ?

    Je fais maintenant comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pj_str_t tools::toPjStr(QString &string)
    {
        const char* c = string.toStdString().c_str();
        char* s = (char *)malloc(string.size());
        strcpy(s, c);
     
        return pj_str(s);
    }
    Mais j'ai toujours mon programme qui crash parfois.

    [edit] : regardez le post suivant pour la version fonctionnelle.
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur réseau et sécurité / Consultant
    Inscrit en
    Août 2005
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur réseau et sécurité / Consultant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2005
    Messages : 1 068
    Points : 493
    Points
    493
    Par défaut
    bonjour,

    je me permets de poster la solution définitive qui fonctionne pour moi.

    encore merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pj_str_t tools::toPjStr(QString &string)
    {
        const char* c = string.toStdString().c_str();
        char* s = (char *)malloc(string.size()+1);  
        strcpy(s, c);
     
        return pj_str(s);
    }
    Il y a 10 types de personnes sur la planète. Ceux qui comprennent le binaire et ceux qui ne le comprennent pas...

  10. #10
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2009
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2009
    Messages : 1 009
    Points : 1 738
    Points
    1 738
    Par défaut
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    pj_str_t tools::toPjStr(QString &string)
    {
        char* s = new char[string.size() + 1];  
        strcpy(s, string.toUtf8().data());
     
        return pj_str(s);
    }

    En effet, toStdString est bien un chemin détourné, voici son code dans Qt 5 :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    inline std::string QString::toStdString() const
    { const QByteArray asc = toUtf8(); return std::string(asc.constData(), asc.length()); }
    Donc on n'a pas besoin de la création d'un std::string intermédiaire pour récupérer le tableau de char.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Heuu, oui, mais non...

    toUtf8, comme le nom l'indique, c'est de l'UTF-8.

    Si les 127 premiers caractères sont corrects (bon, je te l'accorde, cela fait la plupart des caractères utilisés en français), les caractères "multi bytes" seront incorrects.

    Car, à défaut d'être mieux informé, il faut considérer que le charset manipulé par pj_str_t est de type ASCII et non UTF-8.

    Ce raisonnement est certes restrictif, mais il a l'énorme avantage d'être sur d'éviter toute erreur, alors que si tu te base sur le principe que pj_str_t est en mesure de manipuler l'UTF-8 et que ce n'est pas le cas, tu risques de te retrouver avec des erreurs qu'il te sera très difficile de retrouver, car n’apparaissant que pour quelques caractères bien particuliers

    Quelque part, je trouve dommage que Qt ait frappé la fonction toAscii d'obsolescence, car cela nous empêche d'utiliser toute bibliothèque (C) qui ne serait pas encore en mesure de manipuler l'UTF-8 (ou, plutôt, cela implique que Qt estime que toutes les bibliothèques C sont en mesure de le manipuler, ce qui est loin d'être prouvé
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Conversion entre QChar et QString
    Par Invité dans le forum Débuter
    Réponses: 5
    Dernier message: 11/03/2013, 11h50
  2. [Socket] Conversation entre 2 ordi
    Par madislak dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 05/11/2006, 10h41
  3. Réponses: 5
    Dernier message: 30/08/2006, 15h10
  4. Fin de conversation entre client et serveur
    Par Stany dans le forum C++
    Réponses: 2
    Dernier message: 15/07/2005, 11h07
  5. conversion en QString
    Par transistor49 dans le forum C++
    Réponses: 5
    Dernier message: 08/03/2005, 13h52

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