FORUM Tom's Hardware » Programmation » C / C++ / Java » [C++ .NET] Comment passer un pointeur d'objet managé à un thread?
 

[C++ .NET] Comment passer un pointeur d'objet managé à un thread?

Il y a 203 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici



Mot :   Pseudo :  
 
Bas de page
Auteur
 Sujet : [C++ .NET] Comment passer un pointeur d'objet managé à un thread?
 
Plus d'informations

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

Code :
  1. ref class CLantronix
  2.     {
  3.         private:
  4.             //Variables de communication
  5.             UdpClient^ ClientUDP;
  6.             IPEndPoint^ NoeudIpDistant;
  7.             String^ IpDestination;
  8.             int PortDestination;
  9.             static bool EcouteEnCours = false;
  10.             static bool MessageRecu = false;
  11.             //Variable concernant le threading
  12.             CThreadEcoute^ oThreadEcoute;
  13.             Thread^ tEcoute;
  14.             Thread^ tAttente;
  15.             void attente();
  16.         public:
  17.             //Constructeurs
  18.             CLantronix(String^ I, int P);
  19.             //La méthode d'envoi (sous deux formes)
  20.             bool envoiTrame(String^ Chaine);
  21.             bool envoiTrame(char* Chaine);
  22.             //La reception synchrone (fonctionne sans problème)
  23.             bool receptionTrame(interior_ptr<array<Byte>^> BufferReception);
  24.             //La reception asynchrome, voici la kwak ^^
  25.             bool startEcoute(interior_ptr<array<Byte>^> BufferReception);
  26.             bool stopEcoute();
  27.     };
 


La classe CThreadEcoute:

 
Code :
  1. ref class CThreadEcoute
  2.     {
  3.         public:
  4.             CThreadEcoute(int PE, UdpClient^, interior_ptr<array<Byte>^> BR);
  5.             //La méthode "Threadée"
  6.             static void executerThread();
  7.             static bool MessageRecu;
  8.         private:
  9.             //C'est ca qu'il me faudrait idéalement, mais c'est interdit par le language... :(
  10.             //static interior_ptr<array<Byte>^> BufferReception;
  11.             static int PortEcoute;
  12.             static UdpClient^ ClientUDP;
  13.             static IPEndPoint^ NoeudIpDistant;
  14.             //Méthode lancée lors de l'arrivée d'un paquet udp
  15.             static void traiterMessage(IAsyncResult^ asyncResult);
  16.     };
 


Explication du stuut:

 

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

 
Code :
  1. BytesRecus = gcnew array<Byte>(1);
  2. 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:

 
Code :
  1. //Lance une réception non bloquante. Dès qu'une trame asynchrone est lue, l'écoute se termine
  2. bool CLantronix::startEcoute(interior_ptr<array<Byte>^> BufferReception)
  3. {
  4.     //Démarrage du thread d'écoute sur le port spécifié
  5.     oThreadEcoute = gcnew CThreadEcoute(PORT_ECOUTE, ClientUDP, BufferReception);
  6.     tEcoute = gcnew Thread(gcnew ThreadStart(oThreadEcoute->executerThread));
  7.     tEcoute->Name = "Thread Ecoute";
  8.     tEcoute->Start();
  9.     //Démarrage du thread d'attente (cf. plus bas)
  10.     tAttente = gcnew Thread(gcnew ThreadStart(this, &CLantronix::attente));
  11.     tAttente->Name = "Thread Attente";
  12.     tAttente->Start();
  13.     EcouteEnCour = true;
  14.     return true;
  15. }
 

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:

 
Code :
  1. void CLantronix::attente()
  2. {
  3.     //tant qu'il n'y a pas eu de message on attend et on passe la main
  4.     while(!oThreadEcoute->MessageRecu) Thread::Sleep(100);
  5.     stopEcoute();
  6. }
 


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

 
Code :
  1. void CThreadEcoute::executerThread(void)
  2. {
  3.     UdpState^ EtatUDP = gcnew UdpState();
  4.     EtatUDP->NoeudIpDistant = NoeudIpDistant;
  5.     EtatUDP->ClientUDP = ClientUDP;
  6.         //On commence l'écoute
  7.     ClientUDP->BeginReceive(gcnew AsyncCallback(traiterMessage), EtatUDP);
  8.     MessageRecu = false;
  9.       //Si pas de message, on laisse un peu la main.
  10.       while (!MessageRecu)
  11.       {
  12.           Thread::Sleep(100);
  13.       }
  14. }
 

=> qui appelle automatiquement la méthode traiterMessage quand qqch est arrivé:

 
Code :
  1. void CThreadEcoute::traiterMessage(System::IAsyncResult ^asyncResult)
  2. {
  3.     UdpClient^ ClientUDP = ((UdpState^)(asyncResult->AsyncState))->ClientUDP;
  4.     IPEndPoint^ NoeudIpDistant = ((UdpState^)(asyncResult->AsyncState))->NoeudIpDistant;
  5.     try
  6.     {
  7.         *BufferReception = ClientUDP->EndReceive(asyncResult, NoeudIpDistant);
  8.     }
  9.     catch (Exception^){}
  10.     MessageRecu = true;
  11. }
 

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:

Code :
  1. 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 :D :yaisse2:

 

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

  


__________________________________
Modérateur: j'ai remplacé [QUOTE] par [CODE]. Merci de respecter ce point de règlement à l'avenir.


Message édité par zeb le 26-02-2008 à 10:33:44

Plus d'informations

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 :king:

Merci tous ;)

zeb
Profil : Modérateur libre

A l'heure où je t'écris, 17 personnes t'ont lues. :o
Sans te donner de réponses :(
Mais tu l'as fait toi-même, merci pour le forum :jap:


---------------
Règlement du forum / Règlement de Programmation / Règlement du Monde de Linux euh, n'y en a pas...
Plus d'informations

Bah de rien ;) faut bien dire ce qui est, le problème était vaste a exposer ^^'

Par contre si quelqu'un savait m'éclairer sur une manière de faire pour n'avoir qu'une seul instance d'un thread? Enfin, un seul thread d'écoute à la fois quoi.

Aller, la bien bonne journée a tous ;)

zeb
Profil : Modérateur libre

Pas bien compris la problématique ?

Pour éviter les redondances de threads à l'intérieur d'un même programme, on peut utiliser une variable de classe.


---------------
Règlement du forum / Règlement de Programmation / Règlement du Monde de Linux euh, n'y en a pas...
Profil : Pointeur
Plus d'informations

un singleton ?


---------------
Da Bidz Triad©®™: Bidz Interceptor
.:: Smileyz version 4.2 [050625]::. -- Code source disponible sous licence GPL.
[u

Aller à :
 
  FORUM Tom's Hardware » Programmation » C / C++ / Java » [C++ .NET] Comment passer un pointeur d'objet managé à un thread?

Annonces Google
Publicité
Actualités relatives

La souris de Microsoft qui fait télécommande

Publié le 12 January 2007

Présentée fin octobre (cf. Microsoft présente ses accessoires pour PC), la souris Wireless Notebook Presenter Mouse 8000 de Microsoft arrive en vente. Pointeur laser et télécommande Il s’agit d’abord d’une souris ambidextre sans fil à la norme Bluetooth, Lire la suite

Le Niagara 2 en double pour 2008

Publié le 07 February 2007

Le Niagara 2 de Sun, un processeur massivement multi-core, va sortir dans une déclinaison plus performante en 2008, le Victoria Falls (Chutes Victoria). Le Niagara 2 est un processeur octo-core capable d’exécuter 8 thread par core. C’est une amélioratio ... Lire la suite

Trust dévoile le Wireless Presenter

Publié le 21 May 2005

Cette actualité est l'occasion de parler d'une catégorie de produits dont nous parlons peu mais qui s'avère très pratique : les télécommandes permettant de commander une présentation. En effet, quoi de plus classe pour vos réunions où vou Lire la suite

Une souris qui présente bien

Publié le 13 September 2007

Lors d’une présentation à des clients, des collaborateurs, etc. on est souvent amené à pointer sur l’écran un élément critique. Dans ces cas-là, le professionnel peu prévoyant se retrouve à essayer de montrer avec son doigt, sans pour autant masquer la mo ... Lire la suite

Les derniers tests

Que choisir ? Home Cinema 5.1 ou projecteur de son ?

Publié le 25 September 2008

Faut-il craquer pour un ensemble 5.1 ou pour une barre de son ? Découvrez les forces et faiblesses comparées de chaque système. Lire la suite

Intel Core i7 (Nehalem) : une architecture signée AMD ?

Publié le 25 September 2008

Avec ses nouveaux processeurs Core i7, Intel fait évoluer les Core 2 en reprenant leur architecture, mais en lui rajoutant des technologies dont la plupart semblent avoir leur équivalent direct chez AMD. Impression ou réalité ? Lire la suite

Test du Nokia N96 : la vie sans écran tactile

Publié le 24 September 2008

Un téléphone haut de gamme peut il échapper à l'écran tactile ? Nokia a tenté le pari avec le N96. Lire la suite

Les nouveaux disques durs 1 To

Publié le 22 September 2008

Un an et demi après l'introduction du premier disque dur 1 To, les prix ont beaucoup diminué et de nouveaux modèles ont été lancés. Mais comment se comportent-ils entre eux et par rapport aux anciens ? Réponse dans ce comparatif. Lire la suite