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:
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.BytesRecus = gcnew array<Byte>(1);
ObjetCLantronix->startEcoute(&BytesRecus);
La m�thode startEcoute:
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.//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;
}
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:
=> qui appelle automatiquement la m�thode traiterMessage quand qqch est arriv�: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);
}
}
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?? :/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;
}
- 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:
il prend directement ca comme interior_prt<array<Byte>^> ... Peut-�tre un moyen de le forcer?startEcoute(&BufferReception)
==> 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![]()
Partager