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

Delphi .NET Discussion :

Comment importer une DLL dans du code??? [FAQ]


Sujet :

Delphi .NET

  1. #21
    Membre émérite
    Avatar de Merlin
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mars 2002
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 524
    Points : 2 883
    Points
    2 883
    Par défaut
    Faire marcher "n'importe quelle DLL" me semble impossible par nature. Si ton application n'a pas connaissance à l'avance des signatures des méthodes des classes, je vois mal comment elle pourrait les appeler en leur passant par exemple les "bons" paramètres.
    C'est pas jouable conceptuellement.
    Lorsqu'une appli charge des dll dynamiquement, elle connait toujours ce qu'il a dedans. La gestion des plugins est par exemple souvent basée là desus, chaque dll peut avoir des fonctions très différentes mais pour être reconnue comme plugin utilisable elle doit, par force, exporter un certain nombre de choses fixées à l'avance qui forme le protocole, le contrat entre l'appli et ses plugins.
    Donc soit j'ai pas tout compris (ce qui est possible), soit ce que tu veux faire est de toute façon impossible.

  2. #22
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut
    Ben je pense que ca doit etre possible puisque le logiciel réflector le permet ( logiciel permettant d'explorer n'importe quelle DLL.)

    En fait je suis obliger de procéder ainsi car je dois réaliser un séquenceur de test générique qui va permettre de réaliser n'importe quel banc de test rapidement (pour le test de cartes électroniques)... l'utilisateur du séquenceur pourra par la suite lancer n'importe quel test en appelant les DLL qui vont bien en fonction des tests qu'il veut réalisé (voila en quelque mot ).

    Mais je voit peut etre une autre solution, j'ai cru comprendre que l'on pouvait via la réflection récupérer le contenu de toute une fonction (son code) et puisque c'est moi par la suite qui vait créer les DLL utilisables par le séquenceur je n'ai qu'a créer une fonction commune à chaque DLL qui renfermerai le prototype de toutes les fonction qu'elle contienne....

    En sais tu d'avantage sur cette possibilité (récupération du code d'une fonction )?

    merci d'avance
    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  3. #23
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Oh le cas intéressant! Un cas de projet de développement sans conception.

    Vous confondez 2 usages distincts de la reflection:
    1) Charger l'assembly dans le code pour instancier l'un de ces types.
    2) Coder un explorateur de types.

    D'abord, vous avez découvert le projet winform Delphi.Net Reflect et à tord ou à raison vous souhaitez intégrer ce code dans votre projet.
    (Ca rassure et donne le sentiment d'avoir bien progresser, on a du code!)
    Ensuite, vous cherchez à construire votre projet autour de ce code.

    Comprenez qu'un explorateur de type est à l'usage d'un utilisateur qui souhaite par exemple s'informer de la signature d'une méthode,
    ce qui ne correspond pas au besoin de votre projet, et que d'autre part, comme le souligne Merlin,
    il est vain de vouloir opérer des traitements sur des données si l'on pose la condition de vouloir ignorer la nature même de ces traitements.

    Vous écrivez:
    Mais le problème c'est que je ne suis pas sensé connaitre le contenu de mon assemblage donc impossible de faire "string. compare".
    Ce n'est pas le problème.
    Le probleme est de charger des assembly et instancier des types.

    A mon avis, si vous avez par exemple une dll pour chaque type de RAM(edo, sdram) avec un jeu de fonctions en commun , implémentez la pattern Adaptateur,
    créez une interface de base (facade) qu'implémentent les types contenus dans vos DLL et laissez jouer le polymorphisme dans le code.

  4. #24
    Membre émérite
    Avatar de Merlin
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mars 2002
    Messages
    524
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 524
    Points : 2 883
    Points
    2 883
    Par défaut
    Je ne peux qu'agréer les sages conseils de Fabrice.

    Un programme comme Reflector permet d'inspecter un code, pas d'utiliser ce code. Cela fait une nuance importante. Le résultat de reflector sont à usage de l'oeil et de la sagacité humaine, pour documentation.
    On peut se baser sur la reflexion pour "découvrir" les classes exportées et pourquoi pas pour les instancier.
    Mais dans l'exemple pris, la fonction "add", comment l'application peut-elle l'appeler correctement si elle n'a pas été conçue _avant_ pour lui passer les _bons_ paramètres ?
    C'est impossible par nature.

    Il n'y a que deux possibilités raisonnables : soit, comme le conseil Fabrice, utiliser la design pattern decorateur pour habiller chaque dll avec une interface commune, soit créer un outil totalement générique offrant du scripting pour piloter n'importe quelle dll.

    Cette dernière option n'est pas si compliquée à mettre en oeuvre en C# puisqu'on peut compiler du code C# à l'exécution en invoquant les services du compilateur.
    On peut donc supposer un outil avec compilateur c# et debugger permettant d'écrire du code pour piloter les dll.
    Mais cela est malgré tout un projet ambitieux, même s'il est réalisable.

  5. #25
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut
    Bienvenu Fabrice dans cette discussion

    Vous me faites tres peur avec vos deux derniers post, je joue mon diplome la ...

    Non mais y a un truc que je saisi pas trop...

    Vous etes bien d'accord que la réflection permet:

    1--> de connaitre le contenu d'un assemblage

    2--> d'instancier lors de l'exécution une méthode (Invoke)

    Non???

    Alors pourquoi serai-je réveur de penser qu'il m'est alors possible de récupérer le prototype d'une fonction contenu dans un assemblage et de l'instancier...?
    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  6. #26
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut
    Au fait Fabrice j'ai l'impression que tu m'as donné un bout de solution mais je dois dire que je n'ai pas tres bien saisi.... Désolé de me répéter mais je suis loin d'etre une star en développement, je débute

    Peux tu détailler ou m'indiquer un lien qui m'éclaircirait le sujet?
    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  7. #27
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Puisque vous souhaitez effectuer un appel de methode via la reflexion, mettons cela en oeuvre.

    Commençons par créer un projet class library en C#.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    namespace Library1
    {
      using System;
      public class Library1
      {
         public int Add(int a, int b){
            return a + b;
         }
      }
    }
    Maintenant on crée un petit projet console C# pour tester notre dll.
    Remarquez que nous allons cristalliser l'appel à la méthode de classe de l'assembly dans une méthode de même nom.
    Ainsi le code appelant n'a pas à savoir comment s'effectue réellement l'appel.
    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
     
    namespace Project1
    {
     using System;
     using System.Reflection;
     
    public class Test {
     
      static object Add(int a, int b) {
        Assembly assembly = Assembly.LoadFrom("Library1.dll");
        Type type = assembly.GetType("Library1.Library1");
        object target = assembly.CreateInstance("Library1.Library1");
        object[] args = {a,b};
        object result = type.InvokeMember("Add", BindingFlags.InvokeMethod, null, target, args);
        return result;  
      }
     
      public static void Main(string[] args){
      Console.WriteLine("Resultat: " + Test.Add(4,8));
      Console.ReadLine();
      }
    } 
    }
    Pour en revenir à la design pattern Adapteur, l'idée est que les classes de votre projet n'appellent pas directement les méthodes
    des types instanciés de l'assembly dont les signatures diffèrent.
    Elles communiqueront avec une interface.

    Une classe Adaptateur implémentera cette interface et effectuera les appels aux méthodes de l'assembly.

    Ainsi votre code n'aura pas connaissance du mécanisme de la reflexion, c'est à la charge de l'adaptateur.
    Votre code est client de l'interface, l'assembly est l'adapté et la classe Adaptateur se situe entre les deux.

    Ce mécanisme est l'une des voies possibles pour effectuer des appels génériques.
    Une autre méthode proposée par Merlin est de mettre en place une pseudo grammaire et un interpréteur en se basant sur la possibilitée
    de compilation à la volée et d'exécution de code.

  8. #28
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut
    Merci beaucoup Fabrice pour cette exemple qui m'a beaucoup aidé....

    Je l'ai donc adapté a mon problème et en jonglant avec des fichiers textes qui renfermeront quelques info sur mes Dll je devrai m'en sortir...

    J'ai essayé de passé ton exemple (un peu modifié) en Delphi.net et j'obtiens une erreur.

    Voici mon code:
    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
     
       procedure TForm1.AdditionClick(Sender: TObject);
    var
      monObjet, result   : System.Object;
      arguments  : array [1..2] of System.Object;
      SampleAssembly : Assembly;
      tType: System.Type;
    begin
        SampleAssembly := Assembly.LoadFrom('c:\dllAddition.dll');
        tType := SampleAssembly.GetType('dllAddition.dllAddition1');
        monObjet := SampleAssembly.CreateInstance('dllAddition.dllAddition1');
      arguments[1] := a1.Text;
        arguments[2] := a2.Text;
      result := Ttype.InvokeMember('Add', BindingFlags.InvokeMethod, nil, monObjet, arguments);
        resultAdd.Text := string(result);
    end;
    A l'exécution j'ai une erreur à la ligne du "InvokeMember" me disant que le membre n'a pas été trouvé.
    Alors que ce meme code fonction en C# (en adaptant la syntaxe bien sur ).
    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  9. #29
    Membre habitué Avatar de Jayceblaster
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    420
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 420
    Points : 174
    Points
    174
    Par défaut
    Bon j'ai trouvé l'erreur c'est au niveau du type Object...

    Il faut écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        arguments[1] := System.Object (StrToInt(a1.Text));
        arguments[2] := System.Object (StrToInt(a2.Text));
    En C# le problème ne se pose pas car la convertion doit être implicite.

    Ceci dit je trouve cette écriture un peu lourde (j'ai pas trouvé mieux )

    Heureux est l'étudiant qui, comme la rivière, arrive à suivre son cours sans sortir de son lit........

  10. #30
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2006
    Messages
    624
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 624
    Points : 754
    Points
    754
    Par défaut
    Ah les transtypages...
    Pour ma part, je n'ai pas vraiment mieux à proposer.
    On peut écrire également:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     argument[1] := System.Object(System.Convert.ToInt(a1.Text));
    Mais en ce qui me concerne je suis assez réticent à utiliser la VCL.NET.
    Son avenir et son évolution reste incertain.
    Si dans le futur un développeur décide de passer le code en C#, cela passera nécessairement par la réécriture de toutes les interfaces.
    De plus, ces dernières qui s'appuyent sur la VCL.NET ne sont pas partageables entre développeurs dotnet.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Importer une librairie dans un code c++
    Par wikers dans le forum Linux
    Réponses: 6
    Dernier message: 14/08/2009, 00h31
  2. Comment mais une DLL dans un programme
    Par zizo89 dans le forum Delphi
    Réponses: 1
    Dernier message: 20/04/2007, 23h25
  3. Comment intégrer une image dans le code ?
    Par delphi+ dans le forum Delphi
    Réponses: 5
    Dernier message: 06/04/2007, 14h56
  4. Comment importer une DLL Win 32 en delphi.Net?
    Par Mickey.jet dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 21/08/2006, 10h33
  5. [VB] COmment compiler une dll dans un exe (zlib.dll)
    Par Khrysby dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 01/11/2005, 12h10

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