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

Langage Delphi Discussion :

Systeme plugin avec DLL -> fonction external dynamiquement


Sujet :

Langage Delphi

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut Systeme plugin avec DLL -> fonction external dynamiquement
    Salut a tous !!!

    Voila je suis en train de faire un prog avec des plugins. En effet, J'ai un programme hote avec une listbox qui rexupère les noms de mes dll. Lorsque je click sur un des noms, il m'ouvre la dll qui contient une form et tout ce qui va avec à l'interieur de mon programme hote.

    A l'époque ou je voulais faire ça, j'avais vu avec clorish (qui est a mon grand regret sur yahoo messenger que je ne prefere pas utiliser )
    En gros, j'avais une fonction dans ma DLL qui m'ouvrait la form dans le parent window. Voici le principe :

    Dll :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Procedure Launch(App : TApplication; MainForm : TForm);
    Begin
    App.CreateForm(Tmainppe, mainppe); // Remplacer par les types et variables adequates
    mainppe.ParentWindow := MainForm.Handle;
    mainppe.Show;
    End;
     
    Exports Launch;
    Et voici le programme hote :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        Procedure Launch(App : TApplication; MainForm : TForm); external '.\Project1.dll' name 'Launch';

    Mais voila mon gros problème :

    Je n'utilise pas forcement toujours les memes dll. Par contre elles ont toujours cette fonction à l'interieur. Donc comment pourrais-je faire pour ne pas avoir à forcement spécifier le nom de DLL dans la declaration sur mon programme hote (au niveau du external, c'est la ou ca me gene)?

    Pour résumer : apres le external, il ne faut pas que je mette le nom du fichier DLL car je ne le connais pas à l'avance. Donc comment faire pour déclarer ma procédure launch ?

    Merci d'avance
    Z@X

  2. #2
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Il faut charger dynamiquement le librairie, fait une recherche dans le forum avec le mot LoadLibrary
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut NoNo

    J'ai recherché sur le forum a propos de la fonction loadlibrary et j'ai fait l'essai. Ca ne marche pas car il me dit qu'il ne trouve pas ma procedure Launch qui fait partie de ma dll. Elle est pourtant déclarée en export. Je pense qu'il faut lui préciser dans le programme hote qu'il faut aller chercher cette fonction exportée mais comment faire vu que la dll est chargée avec loadlibrary ?
    Merci d'avance

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    En fait c'est bon j'ai récupéré un bout de code du forum et ca a l'air de fonctionner. Je n'aime pas trop ne pas comprendre ce qui est fait mais bon ca fonctionne donc c'est bien.

    Merci

  5. #5
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    C'est qu'il faut aussi donner l'adresse de la fonction en dynamique.

    Voici la méthode : tu déclares la fonction comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Type
      TLaunch = Procedure (App : TApplication; MainForm : TForm); 
    Var
      Launch  :TLaunch;
    ensuite tu cherches l'adresse de la fonction dans la librairie lue en dynamique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @Launch := Nil;
    @Launch := GetProcAddress(HandleDll, 'Launch');
    If @Launch=Nil Then AffErreur('Launch non trouvé');
    Où HandleDll est le Handle retourné par la fonction LoadLibrary.

    Tu utilises dans ton code la fonction Launch comme d'habitude, le compilateur va de lui-même gérer l'appel indirect dans ce cas.

    [edit]10 minutes trop tard [/edit]
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  6. #6
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    Citation Envoyé par zax-tfh
    En fait c'est bon j'ai récupéré un bout de code du forum et ca a l'air de fonctionner. Je n'aime pas trop ne pas comprendre ce qui est fait mais bon ca fonctionne donc c'est bien.

    Merci
    Et il est ou ce bout de code !?

    PAskeu que je suis dans le meme cas que toi et ca ne compile pas chez moi ...

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    837
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Février 2003
    Messages : 837
    Points : 377
    Points
    377
    Par défaut
    Salut subzero2

    Euhhh, c'est a dire que depuis, de l'eau a coulé sous les ponts... lol
    Ca fait quand meme un an, et là je viens de switcher vers le monde macintosh

    Bon pour revenir sur le sujet, en gros je ne me souviens plus de ce qu'il fallait faire mais si tu me rafraichis la memoire en m'expliquant là ou ca coince, genre avec des bouts de codes et le probleme bien expliqué, ca devrait aller.

    Sinon je te conseille de faire une recherche sur le forum des messages de Clorish.
    Il a fait tout un topic tutoriel la dessus mais bon, c'est pas trop evident, enfin je sais que je n'avais po suivi car ca me paraissait trop compliqué pour debuter avec les dll.

    Alors bon, fais comme tu veux, demandes moi ou mates les tutos, en tout cas je serais la si t'as besoin ^^

    @++

  8. #8
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    Merci de te manifester !

    Le bout de 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
    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
    type
      Tata = procedure GetBmpFromRessource(var BmpD, BmpG, BmpUl, BmpL: TBitmap)
     
      TMenuDeroulant = class(TComponent)
      Panel: TPanel;
      BtnMenu: TSpeedButton;
      BtnLock: TSpeedButton;
      Timer: TTimer;
     
       private
          BmpD, BmpG, BmpUl, BmpL: TBitmap;
       public
          constructor Create(AOwner: TComponent); override;
          destructor Destroy; override;
     
          procedure Init(AParent: TWinControl; Pos: TPoint);
       published
     
       end;
     
    implementation
     
    { TMenuDeroulant }
    constructor TMenuDeroulant.Create(AOwner: TComponent);
    var
       NomDll: String;
       HDll: DWORD;
    begin
      inherited;
       NomDll:='MenuRes.dll';
       hDLL:=LoadLibrary(PChar(NomDll)); // chargement de la dll
       if hDLL=0 then ShowMessage('erreur au chargement de la DLL');
       GetBmpFromRessource:=GetProcAddress(hDLL,'GetBmpFromRessource');  // affectation de la fonction de la dll à la fonction du programme
     
       // Cree les 4 images dont on a besoin !
       BmpD := TBitmap.Create;
       BmpG := TBitmap.Create;
       BmpUl := TBitmap.Create;
       BmpL := TBitmap.Create;
       GetBmpFromRessource(BmpD, BmpG, BmpUl, BmpL);
     
       Panel := TPanel.Create(AOwner);
       BtnMenu := TSpeedButton.Create(AOwner);
       BtnLock := TSpeedButton.Create(AOwner);
       Timer := TTimer.Create(AOwner);
    end;
    Et la ou ca coince :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tata = procedure GetBmpFromRessource
    Il me dit "Directive inconnue 'GetBmpFromRessource' "
    Je comprend pas bien le fait de declarer une variable de type procedure ...

  9. #9
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    Personne aurait une tite idée ?
    Ne serait que tres petite ?

  10. #10
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Le prototype d'un type procédure ne nécessite pas de nom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type 
      Tata = procedure (var BmpD, BmpG, BmpUl, BmpL: TBitmap);
    La touche F1, en ayant cliqué au préalable sur l'erreur, pouvait t'orienter :
    La directive est probablement mal orthographiée ou un point-virgule est manquant.

  11. #11
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    je me doute qu'elle etait mal orthographiée
    c'est bien pour ca qu'il y avait une erreur

    Merci kan meme pour cette reponse, je test ca lundi.
    Bon week end a tous !

  12. #12
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    Bon ca marche pas mal pour ce qui est des declarations par contre maintenant, j'ai une violation d'accés au moment ou j'appel cette fonction.

    le code de la DLL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    library MenuRes;
     
    uses
       Graphics;
     
    {$R Ressources.res}
    procedure GetBmpFromRessource(var BmpD, BmpG, BmpUl, BmpL: TBitmap); export
    begin
       BmpD.LoadFromResourceName(HInstance, 'DROITE');
       BmpG.LoadFromResourceName(HInstance, 'GAUCHE');
       BmpUl.LoadFromResourceName(HInstance, 'UNLOCK');
       BmpL.LoadFromResourceName(HInstance, 'LOCK');
    end;
    end.
    et la ou je 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    unit MyUnit;
     
    interface
     
    uses
       Classes, ExtCtrls, Buttons, Graphics, Controls, Types, Windows, Dialogs;
     
    type
      TGetRes = procedure (var BmpD, BmpG, BmpUl, BmpL: Graphics.TBitmap);
     
      TMenuDeroulant = class(TComponent)
     
       private
          GetBmpFromRessource: TGetRes;
          BmpD, BmpG, BmpUl, BmpL: Graphics.TBitmap;
       public
       published
     
       end;
     
    implementation
     
    { TMyUnit }
    constructor TMenuDeroulant.Create(AOwner: TComponent);
    var
       NomDll: String;
       HDll: DWORD;
    begin
      inherited;
       NomDll:='MenuRes.dll';
       hDLL:=LoadLibrary(PChar(NomDll)); // chargement de la dll
       if hDLL=0 then ShowMessage('erreur au chargement de la DLL');
       GetBmpFromRessource := GetProcAddress(hDLL,'GetBmpFromRessource');  // Affecte la fonction de la dll au programme
     
       // Charge les 4 images dont on a besoin !
       BmpD := Graphics.TBitmap.Create;
       BmpG := Graphics.TBitmap.Create;
       BmpUl := Graphics.TBitmap.Create;
       BmpL := Graphics.TBitmap.Create;
       GetBmpFromRessource(BmpD, BmpG, BmpUl, BmpL); // et la ca plante ...
    nb: La ressource existe bien

  13. #13
    Membre chevronné
    Avatar de Pierre Castelain
    Inscrit en
    Avril 2002
    Messages
    523
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 523
    Points : 1 943
    Points
    1 943
    Par défaut
    Tu ne peux pas utiliser une méthode comme point d'entrée de la dll. Il faut utiliser une fonction "classique". Donc, sort la déclaration de GetBmpFromRessource de la classe TMenuDeroulant et tout devrait rentrer dans l'ordre.

    Encore un truc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       @GetBmpFromRessource:=GetProcAddress(hDLL,'GetBmpFromRessource');  // affectation de la fonction de la dll à la fonciion du programme
    C'est l'adresse de la fonction qu'on récupère par l'appel à GetProcAddress, il faut donc indiquer cela au compilateur en insérant le signe @ devant le nom de la variable.

  14. #14
    Débutant

    Inscrit en
    Décembre 2003
    Messages
    166
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 166
    Points : 120
    Points
    120
    Par défaut
    Qu'entend tu par Fonction "classique" ??

    Sinon j'ai fait ca mais rien ne change :
    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
    42
    43
    44
    45
    46
    unit UnitMenuDeroulant;
     
    interface
     
    uses
       Classes, ExtCtrls, Buttons, Graphics, Controls, Types, Windows, Dialogs;
     
    type
       TGetRes = procedure (var BmpD, BmpG, BmpUl, BmpL: Graphics.TBitmap);
     
      TMenuDeroulant = class(TComponent)
      Panel: TPanel;
      BtnMenu: TSpeedButton;
      BtnLock: TSpeedButton;
      Timer: TTimer;
     
       private
          BmpD, BmpG, BmpUl, BmpL: Graphics.TBitmap;
       public
          procedure LoadDll;
       published
     
       end;
     
    var
       GetBmpFromRessource: TGetRes;
       NomDll: String;
       hDLL:THandle;
     
    implementation
     
    { TMenuDeroulant }
    procedure TMenuDeroulant.LoadDll;
    begin
       NomDll:='MenuRes.dll';
       hDLL:=LoadLibrary(PChar(NomDll)); // chargement de la dll
       if hDLL=0 then ShowMessage('erreur au chargement de la DLL');
       @GetBmpFromRessource:=GetProcAddress(hDLL,'GetBmpFromRessource');  // affectation de la fonction somme de la dll à la fonction somme de notre programme
     
       if @GetBmpFromRessource = nil then
       begin
          MessageDlg('Fonction non chargée !', mtWarning, [mbOK], 0);
          FreeLibrary(hDLL);
          Exit;
       end;
    end;

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

Discussions similaires

  1. [AJAX] lien généré dynamiquement avec appel de fonction javascript
    Par karimphp dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 21/11/2007, 10h23
  2. Comment concevoir un systeme de plugin avec java
    Par ghassen_ing dans le forum Langage
    Réponses: 6
    Dernier message: 16/10/2006, 13h29
  3. Réponses: 12
    Dernier message: 12/05/2006, 09h21
  4. [PHP][Javascript] PB avec appel de fonctions externes, HELP!
    Par chaser_T dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 11/04/2006, 16h44
  5. [Système]communiquer avec un processus externe sous windows
    Par tweety dans le forum Général Java
    Réponses: 4
    Dernier message: 14/11/2005, 17h17

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