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++/CLI Discussion :

Problème avec un pointeur global sur une variable manager


Sujet :

C++/CLI

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut Problème avec un pointeur global sur une variable manager
    Bonjour,

    Voilà le contexte :
    J'ai sept champ DataGridView, et en fonction d'une option (du style ListBox), je veux que seul le champ sélectionné par l'option soit modifié par une fonction évenementielle.

    Je voulais donc utiliser un pointeur, modifié dans la fonction de la ListBox, et plus après utilisé dans la fonction évenementielle (réception sur SerialPort).


    J'ai essayé plusieurs choses :
    Dans Form1.h au niveau des déclarations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private: DataGridView ^ *pDGV;
    puis dans Form1.cpp, la fonction évenementielle de la ListBox :
    => Erreur de conversion de cli::array<Type> en DataGridView^ *.


    Puis :
    Dans Form1.h au niveau des déclarations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private: cli::interior_ptr<DataGridView>^ pDGV;
    puis dans Form1.cpp, la fonction évenementielle de la ListBox :
    => Erreur interior_ptr ne peut pas prendre de le type DataGridView.


    J'ai également essayé de déplacer les déclarations ... idem.


    Mais, ces déclarations sont correctes lorsqu'elles sont au niveau d'une fonction.

    Comment déclarer des pointeurs globaux ? Et, est-ce la bonne méthode ?

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    c'est horrible ca comme déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private: DataGridView ^ *pDGV;
    on utilise un handle et puis c'est tout (^) , voir dans la faq C++/CLI http://dotnet.developpez.com/faq/cpp...syntaxe#handle

    ensuite, si tu as besoin de "variables globales" :
    Afin d'avoir une variable accessible de n'importe quel endroit de son application il faut la déclarer static.
    Cette pratique est en général à déconseiller aux débutants, mais peut s'avérer indispensable dans certaines utilisations.
    En général, on créera une classe qui regroupe toutes les variables accessibles de n'importe quel endroit. Il peut s'agir d'une classe de configuration par exemple.

    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
    public ref class MyConfiguration
    {
    private:
       static String ^stringConnection;
    public:
       static property String ^StringConnection
       {
    		String^ get()
    		{
    			return stringConnection;
    		}
     
    		void set(String^ value)
    		{
    			stringConnection = value;
    		}
     
       }
    };
    exemple d'appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	MyConfiguration::StringConnection = "ABC";
    	Console::WriteLine(MyConfiguration::StringConnection);

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    La solution était si simple, c'est déroutant

    Merci infiniment.


    J'aurais deux autres questions du coup (jamais content...) :
    -D'abord, quelle est la syntaxe pour affecter à une String un caractère, du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    String^ maString;
    maString = (0x30);
    //ou encore
    maString = String::Format("{0}",0x30);
    Je voudrais que maString soit égale à "0", comment est-ce possible ?



    -Et puis, comment faire pour récuperer les noms de plusieurs fichiers lors d'un drag and drop ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    System::Void DragDrop(System::Object^  sender, System::EventArgs^  e)
    {
       Object^ mesFichiers;
       String^ leNom;
     
       mesFichiers = e->Data->GetData("FileNameW");
       leNom = mesFichiers[0];
      //C'est fait de tête, alors la syntaxe est peut-être fausse, mais le résultat c'est que mesFichiers ne renvoie jamais un array de string ... ?!
    }

    Merci par avance.

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    je n'ai pas compris, tu veux affecter 0 à ta chaine ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String ^maChaine = gcnew String("0");
    S'il s'agit "d'initialiser" la chaine avec des zéros, comme on pouvait le faire en vieux C, et bien ce n'est pas la peine.

    C'était la question ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Non, pas tout à fait.
    Mon but est de charger un String avec la mémoire tampon de mon SerialPort en lecture séquenciel. Il sort donc un char de type 0x21, 0x23 ... je veux pouvoir affecter à ma String le caractère codé par 0x21, 0x23, de manière à pouvoir les ressortir de ma string sans perte de données.

    Pourquoi utiliser une String ? parce que elle à des méthodes bien pratiques (et simples) pour moi.

  6. #6
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    a mon avis, le plus simple est de passer par un wchar_t temporaire

    du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    wchar_t t[10] = {0x41, 0x42, 0x43, 0};
    String ^s = gcnew String(t);
    sinon, pour ton dernier problème, il faut caster en array de chaine pour savoir s'il y a plusieurs fichiers.
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    private: System::Void monObjet_DragDrop(System::Object^  sender, System::Windows::Forms::DragEventArgs^  e) {
    	 if (e->Data->GetDataPresent(DataFormats::FileDrop))
    	 {
    		 array<String ^> ^files = (array<String ^>^)e->Data->GetData(DataFormats::FileDrop);
    		 MessageBox::Show(Convert::ToString(files->Length) + " fichiers");
    	 }
     }
    private: System::Void monObjet_DragEnter(System::Object^  sender, System::Windows::Forms::DragEventArgs^  e) {
    	 if (e->Data->GetDataPresent(DataFormats::FileDrop))
    		 e->Effect = DragDropEffects::Copy;
    	 else
    		 e->Effect = DragDropEffects::None;
     }
    tout en ayant au préalable autorisé le drag & drop
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monObjet->AllowDrop = true;

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Super, merci, ça marche nickel.

    C'est quand même étrange qu'il n'y ai pas de syntaxe de conversion directe, sans passer par un buffer. Parce que matériellement chaque caractère de la String est forcément codé par un int.

  8. #8
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ben c'est un niveau d'abstraction différent
    ca sera mieux géré avec la classe StringBuilder http://msdn2.microsoft.com/fr-fr/lib...er(VS.80).aspx mais de toutes facons, ca nécessite de passer par des char ou autres, ou au moins de caster

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Bon, alors je pense avoir trouver d'où venait un de mes problèmes, et j'aurais besoin de vous pour un petit coup de pouce :


    Apparemment l'évennement DataReceived de la classe SerialPort est sur un autre thread que le reste de ma Form.

    J'ai vu qu'il fallait utiliser le code "lock" en C#, mais en C++ ?
    De plus les deux threads (voir plus, je ne sais pas ...) sont déclarés implicitement. Alors, est-ce que "lock" fonctionnera ? Est-ce la bonne méthode ?

    Le but étant de simplement pouvoir récupérer les données qui ont générées l'évennement DataReceived.


    Edit : Est-ce que créer une nouvelle classe en dehors de ma Form, avec un passage de données par copie serait une bonne idée ?

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Je vais essayer d'être plus précis :

    j'ai une form, fait avec le designer de VC, à cette form j'ai associé une connection du type SerialPort. J'ai créer une fonction sur l'événement DataReceived de la classe SerialPort. Dans cette fonction je souhaiterais récupérer les données du buffer de réception SerialPort et les stocker directement dans une DataGridView de ma form.

    Problème, lorsque je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char donnéesRecues = serialPort1->BytesToRead();
    dataGridView1->Rows->Add(Convert::ToString(donnéesRecues));
    En debbug à la ligne d'écriture dans ma DGV j'obtient une erreur me disant que je ne peux pas utiliser une variable d'un autre thread. Et en exécution, l'application bug lors de la réception d'un certain nombre d'octet.


    J'ai essayé une autre solution :
    Passer par un buffer soft, que je viens lire périodique (50ms) pour affecter ma DGV, mais les valeur dans mon buffer sont alors complètement erronées.

    Mes questions :
    Comment gère t-on la réception de données avec un SerialPort ?
    S'il y a actuellement plusieurs threads dans mon appli. c'est qu'elles sont implicites. Dois-je les expliciter, et les gérer ?
    Comment permettre l'utilisation correcte d'une variable inter-thread, et ce sans déclarer de thread ?


    Note : J'ai besoin de recevoir les données octet par octet, et par une fonction appelée par l'événement DataReceived. C'est pour faire le lien entre une fonction ErrorReceived et chaque octet recu (y a t-il un autre moyen ?).

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Bon, j'ai fini par réussir à adapter un morceau de code C# en C++, ce qui permet de gérer correctement la réception des données, et leurs stockage.

    Merci à tous.

  12. #12
    Membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Avril 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2005
    Messages : 87
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par sepullayer
    En debbug à la ligne d'écriture dans ma DGV j'obtient une erreur me disant que je ne peux pas utiliser une variable d'un autre thread. Et en exécution, l'application bug lors de la réception d'un certain nombre d'octet.
    Les delegate sont faits pour gérer ça justement : agir sur des éléments graphiques directement depuis un thread. Je te conseille l'article de DrQ http://drq.developpez.com/dotnet/articles/threads/. Il est en C#, mais facilement adaptable en C++/CLI.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Les delegate sont faits pour gérer ça justement : agir sur des éléments graphiques directement depuis un thread. Je te conseille l'article de DrQ http://drq.developpez.com/dotnet/articles/threads/. Il est en C#, mais facilement adaptable en C++/CLI.
    En fait, c'est comme ça que j'ai résolu mon problème. Mais merci d'avoir répondu.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 28/08/2011, 02h39
  2. Réponses: 6
    Dernier message: 31/03/2011, 09h55
  3. Réponses: 9
    Dernier message: 25/10/2007, 17h20
  4. Petit problème avec les pointeurs et variable
    Par mitherkiller dans le forum C
    Réponses: 5
    Dernier message: 09/03/2007, 23h05
  5. Réponses: 2
    Dernier message: 11/09/2006, 13h22

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