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 :

Comment passer un pointeur d'objet managé à un thread?


Sujet :

C++/CLI

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2008
    Messages : 3
    Points : 4
    Points
    4
    Par défaut Comment passer un pointeur d'objet managé à un thread?
    Bonjour tout le monde!

    Je vous préviens, c'est gros xD Tellement qu'une mise en place du problème doit être faite :p Allons-y gaiement!

    Voilà, je me retrouve confronté à un gros problème et malgré différentes possibilités explorées, il m'est apparemment impossible d'effectuer ce que j'essaie de faire.

    Le blème en très cour :p ==> Comment parvenir à amener mon pointeur jusque dans ce thread bien loin??? ^^

    Résumé de l'architecture:

    Je mets en place une communication UDP via la classe UDPClient en C++ .NET. Un intervenant est ma classe de communication CLantronix qui possède des méthodes telles que "envoiTrame" ou encore (et surtout) "startEcoute". starEcoute est représente une reception asynchrone en udp. Dès qu'il y en a une qui survient, l'idéal est qu'elle place le bytes recu dans un buffer qu'on lui a préalablement passé en paramètre.
    Le second intervenant est la classe CThreadEcoute qui ne sert qu'à contenir la méthode "threadée" d'écoute. Pourquoi une classe à part? parce qu'elle a besoin de paramètres. Donc une instance est créée avec les paramètres nécéssaires, et ensuite utilisée dans la création du thread (gcnew ThreadStart(...) ).

    Extraits de codes:

    Classe CLantronix
    ref class CLantronix
    {
    private:
    //Variables de communication
    UdpClient^ ClientUDP;
    IPEndPoint^ NoeudIpDistant;

    String^ IpDestination;
    int PortDestination;
    static bool EcouteEnCours = false;
    static bool MessageRecu = false;

    //Variable concernant le threading
    CThreadEcoute^ oThreadEcoute;
    Thread^ tEcoute;
    Thread^ tAttente;

    void attente();

    public:
    //Constructeurs
    CLantronix(String^ I, int P);

    //La méthode d'envoi (sous deux formes)
    bool envoiTrame(String^ Chaine);
    bool envoiTrame(char* Chaine);

    //La reception synchrone (fonctionne sans problème)
    bool receptionTrame(interior_ptr<array<Byte>^> BufferReception);

    //La reception asynchrome, voici la kwak ^^
    bool startEcoute(interior_ptr<array<Byte>^> BufferReception);
    bool stopEcoute();
    };

    La classe CThreadEcoute:

    ref class CThreadEcoute
    {
    public:
    CThreadEcoute(int PE, UdpClient^, interior_ptr<array<Byte>^> BR);

    //La méthode "Threadée"
    static void executerThread();

    static bool MessageRecu;

    private:

    //C'est ca qu'il me faudrait idéalement, mais c'est interdit par le language...
    //static interior_ptr<array<Byte>^> BufferReception;

    static int PortEcoute;

    static UdpClient^ ClientUDP;
    static IPEndPoint^ NoeudIpDistant;

    //Méthode lancée lors de l'arrivée d'un paquet udp
    static void traiterMessage(IAsyncResult^ asyncResult);
    };

    Explication du stuut:

    Le but initial est de pourvoir, à partir d'un main ou quoi, effectuer une réception asynchrone comme suit:

    BytesRecus = gcnew array<Byte>(1);
    ObjetCLantronix->startEcoute(&BytesRecus);
    Cet appel est non bloquant (principe asynchrone), et le programme ne s'arreterait pas la dessus. quand qqch arriverait, le buffer BytesRecus serait simplement rempli par les méthodes encapsulées.

    La méthode startEcoute:

    //Lance une réception non bloquante. Dès qu'une trame asynchrone est lue, l'écoute se termine
    bool CLantronix::startEcoute(interior_ptr<array<Byte>^> BufferReception)
    {
    //Démarrage du thread d'écoute sur le port spécifié
    oThreadEcoute = gcnew CThreadEcoute(PORT_ECOUTE, ClientUDP, BufferReception);

    tEcoute = gcnew Thread(gcnew ThreadStart(oThreadEcoute->executerThread));
    tEcoute->Name = "Thread Ecoute";
    tEcoute->Start();

    //Démarrage du thread d'attente (cf. plus bas)
    tAttente = gcnew Thread(gcnew ThreadStart(this, &CLantronix::attente));
    tAttente->Name = "Thread Attente";
    tAttente->Start();

    EcouteEnCour = true;

    return true;
    }
    Comme on peut le constater, cette méthode instancie une classe CThreadEcoute pour pouvoir lui passer les paramètre dont elle a besoin, avant de lancer en Thread la méthode executerThread de cette dernière.
    Elle lance également un second thread dont elle possède elle meme la méthode. celui ci à pour rôle de surveiller le premier thread afin de savoir quand il a reçu qqch. Dans ce cas, elle le tue, et se tue ensuite. Donc la réception asynchrone recevra un message et un seul, après quoi tous les intervenants sont tués. La voici a titre indicatif, mais là ne se situe pas le problème:

    La méthode "Threadée" attente:

    void CLantronix::attente()
    {
    //tant qu'il n'y a pas eu de message on attend et on passe la main
    while(!oThreadEcoute->MessageRecu) Thread::Sleep(100);

    stopEcoute();
    }

    On commence avec la première partie interressante maintenant, la méthode "threadée" de la classe CThreadEcoute:

    void CThreadEcoute::executerThread(void)
    {
    UdpState^ EtatUDP = gcnew UdpState();
    EtatUDP->NoeudIpDistant = NoeudIpDistant;
    EtatUDP->ClientUDP = ClientUDP;

    //On commence l'écoute
    ClientUDP->BeginReceive(gcnew AsyncCallback(traiterMessage), EtatUDP);

    MessageRecu = false;

    //Si pas de message, on laisse un peu la main.
    while (!MessageRecu)
    {
    Thread::Sleep(100);
    }
    }
    => qui appelle automatiquement la méthode traiterMessage quand qqch est arrivé:

    void CThreadEcoute::traiterMessage(System::IAsyncResult ^asyncResult)
    {
    UdpClient^ ClientUDP = ((UdpState^)(asyncResult->AsyncState))->ClientUDP;
    IPEndPoint^ NoeudIpDistant = ((UdpState^)(asyncResult->AsyncState))->NoeudIpDistant;

    try
    {
    *BufferReception = ClientUDP->EndReceive(asyncResult, NoeudIpDistant);
    }
    catch (Exception^){}

    MessageRecu = true;
    }
    Et voici tout le noeud du problème: comment est-ce que je parvient à passer le pointeur "BufferReception" du tout début (passé dans la méthode startEcoute) jusqu'ici dans le thread d'écoute?? :/
    - Pas en paramètre car un thread est void xxx (void) d'office
    - Pas de variable membre pointeur dans la classe CThreadEcoute que je pourrait initialiser via le contructeur par que "An interior pointer cannot be declared as a member of a class." (((((((
    - Par pointeur "classique"? mais en écrivant:
    startEcoute(&BufferReception)
    il prend directement ca comme interior_prt<array<Byte>^> ... Peut-être un moyen de le forcer?

    ==> comment parvenir à amener mon pointeur jusque dans ce thread bien loin??? ^^

    ça c'est du problème hein

    Merciiiii d'avance aux plus courageux d'entre vous. Votre est de la plus grande bienvenue

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2008
    Messages : 3
    Points : 4
    Points
    4
    Par défaut Résolu :D
    Merci a tous ceux qui ont yeutés un jette

    J'ai résolu tout ca en me passant du array<Byte>^. J'ai choisi de travailler avec un buffer de type unsigned char* passé au début. De cette manière pas mal de chose ont pu etre résolues: plus de seconde classe "CThreadEcoute", j'ai tout rapatrié dans la classe CLantronix; possibilté de stocke le pointeur uchar* et donc accessible au thread d'écoute . Ca marche nikel maintenant

    Merci tous

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

Discussions similaires

  1. Réponses: 52
    Dernier message: 23/10/2014, 11h22
  2. Réponses: 1
    Dernier message: 03/04/2013, 14h45
  3. Réponses: 15
    Dernier message: 25/06/2007, 09h35
  4. [JACOB] Comment passer un objet par référence à une méthode
    Par zlavock dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 21/03/2005, 18h28

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