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# Discussion :

[Reflection] Passer des arguments typés dans un InvokeMember


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 6
    Par défaut [Reflection] Passer des arguments typés dans un InvokeMember
    Bonjour, dans le projet que je code j'ai besoin d'utiliser la réflection pour mettre a jour des fichiers librairie : dll.

    Je parviens a créer des instances de classes, et a appeler les méthodes basiques, mais je n'arrive pas a spécifier les arguments lorsque ceux ci sont du type de la classe appelée dynamiquement via la réflection...

    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
    20
    21
    22
    23
    24
    25
    26
    27
     
    static object run(string classname, string methodname) 
            {
                Assembly asm = Assembly.LoadFrom("C:\\Documents and Settings\\Marmotte\\Mes documents\\Visual Studio 2005\\Projects\\MaLibrairieTropBien\\MaLibrairieTropBien\\obj\\Release\\MaLibrairieTropBien.dll");
     
                Type type = asm.GetType(classname);
     
                object obj = asm.CreateInstance(classname);
     
                object[] args = new object [2];
                args[0] = "192.168.1.1";
                //args[1] = ref asm.GetType(classname)
     
                type.GetMethod(
     
                object ret = type.InvokeMember(
                    methodname,
                    BindingFlags.Default 
                   | BindingFlags.Public 
                   | BindingFlags.Static 
                   | BindingFlags.InvokeMethod,
                    null,
                    obj,
                    args
                   );
                return ret;
            }
    l'argument est configuré sur ces lignes, sauf que la ligne en commentaire ne marche bien entendu pas c'est juste pour vous donner une idée de ce que je veux envoyer (la référence d'une instance d'une classe de la dll)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    object[] args = new object [2];
    args[0] = "192.168.1.1";
    //args[1] = ref asm.GetType(classname)
    Le prototype de la fonction que je veux appeler est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Public Boolean MaMethodeTropBien (string ip, ref MonObjetTropBien instancetropbien);
    Je ne trouve pas grand chose en rapport avec ça sur internet, si ce n'est que tout le monde utilise des interfaces implementant IDisposal dont je ne saisi pas toujours l'utilité.


    merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Par défaut
    Comme on se retrouve

    Je n'ai pas tout lu dsl, mais une chose m'interpelle...

    je veux envoyer (la référence d'une instance d'une classe de la dll)
    oui donc tu veux envoyer un objet quoi

    obj j'imagine?

    Si oui, alors :
    car tu l'as ecris toi meme dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type type = asm.GetType(classname);
    asm.GetType retourne un type (un objet de type Type) et non un objet de type classname

    je ne sais pas quel message d'erreur tu as avec ta ligne en commentaire, mais je pressent que le "ref" y est pour quelque chose.... J'avous ne jamais utiliser ref, vu qu'on accede d'office (si j'ai bien compris) aux objets par reference.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 6
    Par défaut
    l'argument que je veux envoyer c'est l'instance d'un objet qui n'existe que dans la dll que je viens de charger.

    Sauf que la partie que je sais pas faire marcher est que je dois envoyer une référence de l'objet : le fameux ref (comme un pointeur en C si j'ai bien compris). Je ne sais pas si c'est une erreur de design ou quoi mais je ne trouve pas comment faire qu'un des arguments soit un ref dans le cas de la reflection

    donc en gros :

    je veux envoyer (la référence d'une instance d'une classe de la dll)
    oui donc tu veux envoyer un objet quoi
    non je veux envoyer la ref d'un objet

    sauf que quand je met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ligne 21: object Instance_Pour_Argument = asm.CreateInstance(classname);
     
    ligne 23 : args[1] = ref Instance_Pour_Argument;
    le compilateur me sors une erreur de syntaxe. Normal vu que j'ai écris cette dernière ligne au "feeling".



    je ne sais pas quel message d'erreur tu as avec ta ligne en commentaire, mais je pressent que le "ref" y est pour quelque chose.... J'avous ne jamais utiliser ref, vu qu'on accede d'office (si j'ai bien compris) aux objets par reference
    quelqu'un peut confirmer?

    EDIT :
    tuto sur l'utilisation de ref en reflection
    http://csharpfeeds.com/post/1724/Csh...on_Part_5.aspx

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 6
    Par défaut
    j'ai trouve, mais j'ai bien lutte donc je vais mettre ma solution ici (reprise de l'exemple plus haut)

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    /*unsafe imperatif pour utiliser une sorte de pointeur sur classe, c'est moche, c'est comme ca...*/
     
    unsafe static void run(string classname, string methodname) 
            {
                //chargement dynamique de la dll
                Assembly asm = Assembly.LoadFrom("C:\\Documents and Settings\\Marmotte\\Mes documents\\Visual Studio 2005\\Projects\\Library\\Library\\obj\\Release\\Library.dll");
     
                //recuperation d'un type de la classe que l'on veut instancier
                Type type = asm.GetType(classname);
     
                //creation de l'instance de la classe objet
                object objetA = Activator.CreateInstance(type);
     
                //initialisation des types des parametres de la methode, ici (string, string, ref Classe_test)
                Type[] arrTypes = new Type[3];
                arrTypes.Initialize();
                arrTypes.SetValue(Type.GetType("System.String"), 0);
                arrTypes.SetValue(Type.GetType("System.String"), 1);
                //ajout du & devrait permettre d'acceder a l'addresse de l'instance du type Classe_test.
                arrTypes.SetValue(Type.GetType(type.ToString()+"&"), 2);
     
                //mais ca ne fonctionne pas ici
                //arrTypes = null aussi, bizarrement
                //la ligne suivante plante : //Console.WriteLine(arrTypes.GetValue(2).ToString());
     
                //la ligne ci dessous devrait trouver la methode Discover dans la classe Classe_test
                //MethodInfo myMeth = type.GetMethod(methodname, arrTypes); //mais ne fonctionne pas!
                MethodInfo myMeth = type.GetMethod(methodname);//fonctionne en revanche
     
                //reglage des parametres
                object[] arrParms = new object[3];
                arrParms.SetValue("192.168.1.1", 0);
                arrParms.SetValue("ERtyu=123", 1);
                arrParms.SetValue(asm.CreateInstance(classname), 2);
     
                //invoke, on sait que la methode renvoi un bool
                bool success = (bool)myMeth.Invoke(objetA, arrParms);
     
                Console.WriteLine("resultat de la discovery : {0}",success);
            }
    EDIT : donc je ne maitrise pas encore vraiment, mais au moins ca fonctionne :/

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2007
    Messages : 257
    Par défaut
    Bonsoir,
    Pour récupérer la référence d'un objet en C# lors d'une affectation, si l'objet en question est de type référence alors on manipule toujours une référence. Le mot clé "ref" sert juste à transmettre des objets de type valeur par référence, à une fonction.

    Donc avec ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     args[1] = Instance_Pour_Argument;
    Sachant que Instance_Pour_Argument est de type object et donc de type référence, alors dans l'affectation, c'est juste une affectation de référence qui est faite, et donc tu récupère bien ta référence.

    Je ne suis pas expert mais je pense que j'avais bien compris cette partie en C#.

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

Discussions similaires

  1. Pb pour passer des arguments dans l'edi
    Par altair8080 dans le forum Code::Blocks
    Réponses: 4
    Dernier message: 17/07/2013, 09h21
  2. [Cookies] passer des arguments dans un form
    Par killer_instinct dans le forum Langage
    Réponses: 2
    Dernier message: 19/04/2007, 22h36
  3. Passer des arguments au binaire/exécutable
    Par Ljungberg dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 03/02/2006, 10h37
  4. Réponses: 6
    Dernier message: 21/12/2005, 18h52
  5. Comment passer des argument a un script php ?
    Par Florina dans le forum Linux
    Réponses: 2
    Dernier message: 11/12/2005, 14h38

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