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 :

Parser des commandes (recv) proprement/efficacement ?


Sujet :

C++/CLI

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Par d�faut Parser des commandes (recv) proprement/efficacement ?
    Bonjour, je me permet de poster cette question, j'ai cr�er un petit programme client /serveur en C++. Cependant je me demandais si il y avait en C++ un moyen de parser proprement les commandes que je r�ceptionne avec rcv() pour �viter de me retrouver avec des if() else() � rallonge.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void MyTCPclient::parseCommande(char * buffer) {
    	if (strcmp ("com1",buffer) != 0) {
    		// appel fonction MyTCPclient::com1
    	}
    	if (strcmp ("com2",buffer) != 0) {
    		// appel fonction MyTCPclient::com1
    	}
    	if (strcmp ("com3",buffer) != 0) {
    		// appel fonction MyTCPclient::com1
    	}
    ...
    }
    Pour avoir plutot un truc du genre (JAVA):

    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
    20
    21
    22
    23
    24
    25
    26
     
    package test;
     
    import java.lang.reflect.Method;
     
    public class ClassMethodTest {
     
    	public static void main(String args[]) throws Exception {
     
    		Testing t = new Testing("val1", false);
    		Class tClass = t.getClass();
     
    		Method gs1Method = tClass.getMethod("getString1", new Class[] {});
    		String str1 = (String) gs1Method.invoke(t, new Object[] {});
    		System.out.println("getString1 returned: " + str1);
     
    		Method ss1Method = tClass.getMethod("setString1", new Class[] { String.class });
    		System.out.println("calling setString1 with 'val2'");
    		ss1Method.invoke(t, new Object[] { "val2" });
     
    		str1 = (String) gs1Method.invoke(t, new Object[] {});
    		System.out.println("getString1 returned: " + str1);
     
    	}
    }
    }
    En gros de pouvoir appeler toutes mes m�thodes seulement en une condition. (je sais pas si c'est tr�s clair ce que je raconte )

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    En C++/CLI, tu peux r�cup�rer une m�thode de classe par son nom, mais je ne le conseillerais pas de toute fa�on.
    Utilise un Dictionary<String^, Delegate^> � la place. Et utilise quelque chose de plus �volu� que recv().

    ...Ou en C++11 natif, tu peux utiliser une std::map<std::string, std::function<(prototype commun � toutes tes fonctions de traitement)> >.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    En C++/CLI, tu peux r�cup�rer une m�thode de classe par son nom, mais je ne le conseillerais pas de toute fa�on.
    Utilise un Dictionary<String^, Delegate^> � la place. Et utilise quelque chose de plus �volu� que recv().

    ...Ou en C++11 natif, tu peux utiliser une std::map<std::string, std::function<(prototype commun � toutes tes fonctions de traitement)> >.
    Quelle serait une solution plus �volu� que recv(), sachant que j'utilise du C++ natif ?

    Je vais test� la solution avec std::map, cependant je me demandais si mes fonctions ont chacune un type diff�rents si cela fonctionnerait ?

  4. #4
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Si tu programmes en C++ natif, pourquoi postes-tu dans la section consacr�e au langage C++/CLI?

    je me demandais si mes fonctions ont chacune un type diff�rents si cela fonctionnerait
    H�las non. Le plus simple sera de faire, pour chaque fonction, une fonction qui r�cup�re les diff�rents arguments puis appelle l'original (dans le milieu des Appels de Proc�dure Distante, on appelle �a un "stub").
    Si tu programmes en C++11, tu devrais pouvoir faire �a assez facilement avec des fonctions lambda.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 504
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 504
    Par d�faut
    Regardez du cot� du Design Pattern "Command".

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    162
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 162
    Par d�faut
    Citation Envoy� par M�dinoc Voir le message
    Si tu programmes en C++ natif, pourquoi postes-tu dans la section consacr�e au langage C++/CLI?

    H�las non. Le plus simple sera de faire, pour chaque fonction, une fonction qui r�cup�re les diff�rents arguments puis appelle l'original (dans le milieu des Appels de Proc�dure Distante, on appelle �a un "stub").
    Si tu programmes en C++11, tu devrais pouvoir faire �a assez facilement avec des fonctions lambda.
    Heu oui .. je viens de me rendre compte que je me suis tromp� de section de forum... (boulet le type j'ai voulu all� trop vite )
    M'enfin les r�ponses attisent ma curiosit�, je peux trouver de la doc sur le site � propos des "stubs" ?
    Si vous avez des liens utiles je suis preneurs.

  7. #7
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    En gros, le proxy et le stub sont deux objets qui servent d'interm�diaires, et donc le code est le plus souvent g�n�r� par des outils (je prends l'exemple de Java ici, qui marche ainsi pour son proc�d� de Remote Method Invocation (RMI)).

    Si je pars de cet exemple:
    Code C++ : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    class Machin
    {
    public:
    	void Hello(void);
    	int FaireTruc(string const &chn, int a, int b);
    };

    Le proxy, c'est ce qu'il y a c�t� client, qui fera un truc de ce genre:
    Code C++ : 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
    20
    21
    22
    23
    24
    25
    class MachinProxy
    {
    private:
    	Reseau& monReseau;
    	int monId;
    public:
    	MachinProxy(Reseau& reseau, int id) : monReseau(reseau), monId(id) { }
     
    	void Hello(void) {
    		Appel appel;
    		appel.SetThisId(monId);
    		appel.SetNomMethode("Hello");
    		monReseau.AppelDistant(appel);
    	}
    	int FaireTruc(string const &chn, int a, int b) {
    		Appel appel;
    		appel.SetThisId(monId);
    		appel.SetNomMethode("FaireTruc");
    		appel.SetString(0, chn);
    		appel.SetInt(1, a);
    		appel.SetInt(2, b);
    		monReseau.AppelDistant(appel);
    		return appel.GetInt(Appel::Retour);
    	}
    };

    Le stub, c'est ce qu'il y a c�t� client, qui fera un truc du genre:
    Code C++ : 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
    20
    21
    22
    23
    24
    25
    class MachinStub : public StubBase //Doit forcément être le premier et non-virtuel
    {
    private:
    	Machin& leVraiMachin;
    public:
    	MachinStub(Machin& machin) : StubBase(), leVraiMachin(machin) { }
     
    	virtual map<string, PtrFonction> GetMap()
    	{
    		map<string, PtrFonction> ret;
    		ret["Hello"] = static_cast<PtrFonction>(&MachinStub::Hello); //Ça DOIT passer avec static_cast, sinon ça veut dire qu'on fait n'importe quoi.
    		ret["FaireTruc"] = static_cast<PtrFonction>(&MachinStub::FaireTruc);
    	}
     
    private:
     
    	void Hello(Appel &appel) {
    		(void)appel; //Hello est une fonction void(void), rien à traiter ici
    		leVraiMachin.Hello();
    	}
    	void FaireTruc(Appel &appel) {
    		int retour = leVraiMachin.FaireTruc(appel.GetString(0), appel.GetInt(1), appel.GetInt(2));
    		appel.SetInt(Appel::Retour, retour);
    	}
    };

    Attention par contre, c'est du code pr�-C++11, on doit probablement pouvoir faire beaucoup plus propre de nos jours avec std::function<>, au niveau de remplissage de la map.

    Je joins le code complet que j'ai utilis� pour mod�liser mon exemple. Il compile, mais il foire probablement � l'�dition de liens, vu que rien n'est impl�ment�.
    Code C++ : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <string>
    #include <exception>
    #include <map>
    using namespace std;
     
    class Machin
    {
    public:
    	void Hello(void);
    	int FaireTruc(string const &chn, int a, int b);
    };
     
    class Appel
    {
    public:
    	static const int Retour = -1;
    	void SetNomMethode(string nom);
    	void SetThisId(int id);
    	void SetInt(int index, int valeur); 
    	void SetString(int index, string valeur);
     
    	string GetNomMethode() const;
    	int GetThisId() const;
    	int GetInt(int index) const;
    	string GetString(int index) const;
    private:
    	//Blabla implémentation
    };
     
    class Reseau
    {
    public:
    	void AppelDistant(Appel &);
    };
     
    class MachinProxy
    {
    private:
    	Reseau& monReseau;
    	int monId;
    public:
    	MachinProxy(Reseau& reseau, int id) : monReseau(reseau), monId(id) { }
     
    	void Hello(void) {
    		Appel appel;
    		appel.SetThisId(monId);
    		monReseau.AppelDistant(appel);
    	}
    	int FaireTruc(string const &chn, int a, int b) {
    		Appel appel;
    		appel.SetThisId(monId);
    		appel.SetString(0, chn);
    		appel.SetInt(1, a);
    		appel.SetInt(2, b);
    		monReseau.AppelDistant(appel);
    		return appel.GetInt(Appel::Retour);
    	}
    };
     
    class StubBase
    {
    protected:
    	typedef void(StubBase::*PtrFonction)(Appel &appel); //En C++11, on peut probablement utiliser std::function<void(Appel&)> à la place
     
    	virtual map<string, PtrFonction> GetMap() = 0;
    private:
    	map<string, PtrFonction> maMap;
    public:
    	void Initialiser() { //Doit être appelée APRÈS avoir construit l'objet complètement
    		maMap = GetMap();
    	}
     
    	void TraiterAppel(Appel& appel) {
    		PtrFonction ptr = maMap[appel.GetNomMethode()];
    		if(!ptr)
    			throw exception("Méthode inconnue");
     
    		(this->*ptr)(appel);
    	}
    };
     
    class MachinStub : public StubBase //Doit forcément être le premier et non-virtuel
    {
    private:
    	Machin& leVraiMachin;
    public:
    	MachinStub(Machin& machin) : StubBase(), leVraiMachin(machin) { }
     
    	virtual map<string, PtrFonction> GetMap()
    	{
    		map<string, PtrFonction> ret;
    		ret["Hello"] = static_cast<PtrFonction>(&MachinStub::Hello); //Ça DOIT passer avec static_cast, sinon ça veut dire qu'on fait n'importe quoi.
    		ret["FaireTruc"] = static_cast<PtrFonction>(&MachinStub::FaireTruc);
    	}
     
    private:
     
    	void Hello(Appel &appel) {
    		(void)appel; //Hello est une fonction void(void), rien à traiter ici
    		leVraiMachin.Hello();
    	}
    	void FaireTruc(Appel &appel) {
    		int retour = leVraiMachin.FaireTruc(appel.GetString(0), appel.GetInt(1), appel.GetInt(2));
    		appel.SetInt(Appel::Retour, retour);
    	}
    };

    Si ton but ultime est de re-cr�er une telle infrastructure, je rappelle qu'il conviendrait d'y inclure un utilitaire qui g�n�re, � partir de la classe Machin, les fichiers MachinProxy.cpp et MachinStub.cpp.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Transmettre des commandes à un process lancé par ksh
    Par jojolepabo dans le forum Linux
    R�ponses: 3
    Dernier message: 19/10/2005, 16h05
  2. R�ponses: 3
    Dernier message: 24/05/2004, 16h20
  3. parser des fichier .xml en perl
    Par djibril dans le forum Modules
    R�ponses: 13
    Dernier message: 18/05/2004, 17h08
  4. Interception des commandes in et out
    Par KDD dans le forum x86 16-bits
    R�ponses: 13
    Dernier message: 18/12/2002, 16h55
  5. [langage]fonction perl pour exécuter des commandes consoles
    Par S�bastien dans le forum Langage
    R�ponses: 3
    Dernier message: 02/09/2002, 18h49

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