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 :

TBitmap et chargement depuis une DLL


Sujet :

Langage Delphi

  1. #1
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut TBitmap et chargement depuis une DLL
    Salut à tous

    J'ai créé un système de plugin (DLL) pour mon application. Pour cela, chaque plugin a une procedure exportée qui transmet les informations du plugin (nom, rang, pleins d'autres choses et surtout icône).
    Cette procédure admet un paramètre qui est une classe contenant uniquement ces informations.
    Chaque plugin contient son propre icône en ressource. La classe contenant les informations contient entre autres un TBitmap créé à la création de la classe et détruit à se destruction. Jusque là, rien d'anormal.
    L'appel à cette fonction du plugin renseigne les informations et charge la ressource dans le TBitmap. Tout s'affiche correctement mais à la fermeture (donc à la destruction du TBitmap) j'ai une belle access Violation Error des familles que j'essaie de corriger depuis quelques jours maintenant.

    Je pense avoir identifié le problème sans en être vraiment sûr: D'après ce que j'ai lu, TBitmap ne contient pas à proprement parler une image mais pointe vers un handle de l'image. C'est pour cela qu'une copie de TBitmap est ultra rapide.
    Donc, je me retrouve à la sortie de la procédure avec un TBitmap qui pointe potentiellement vers un handle qui n'existe plus (puisque "contenu" par le plugin déchargé à la sortie de l'appel à la procédure). Mais le fait que l'image s'affiche correctement me fait douter de cette raison.

    Donc j'ai essayé de rendre mon TBitmap indépendant mais rien à faire... FreeImage ne donne rien, ReleaseHandle ne donne rien, dessiner la ressource sur le TBitmap ne donne rien bref, aucun succès jusqu'à aujourd'hui.

    La seule particularité de cette image est qu'elle est issue d'un PNG donc avec de la transparence.

    Quelqu'un connait-il la solution de ce mystère ?
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    je n'ai pas compris le fonctionnement de tes plugins (qui doivent manifestement utiliser ShareMem)

    voir le chapitre 19 de mon livre sur Delphi 7 qui traite du sujet en détail.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut Paul
    Tu penses bien que j'ai déjà lu ton bouquin

    Et oui, j'utilise SimpleShareMem parce que ça me simplifie la vie... Et que je n'ai pas le choix

    En fait, l'exécutable appelle une fonction exportée de chaque plugin qui sert à spécifier les informations propres à chaque plugin.
    Cette fonction accepte une classe comme paramètre qui conserve ces informations. Cette classe contient entre autres un TBitmap contenant l'image à afficher sur l'interface (bouton et menu).
    Dans chaque plugin, après avoir spécifié les informations (nom, nom à afficher, aide, rang, etc.) je charge une ressource incluse dans la DLL avec LoadFromResourceName du TBitmap de la classe passé en paramètre.

    Tout s'affiche correctement mais j'ai une AV à la destruction de l'appli qui se produit à la destruction du TBitmap.

    J'ai réussi à corriger ce problème en chargeant la ressource depuis l'exécutable de cette façon simple:
    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
     
    function LoadPluginImage(const FileName: String; aBitmap: TBitmap): Boolean;
    var
      HM: HMODULE;
    begin
      HM := LoadLibrary(PChar(FileName));
      if HM = 0 then //Sortie si le chargement de la DLL a échoué
      begin
        Result := false;
        Exit;
      end;
     
      Result := True;
      if FindResource(HM, PChar('PluginImage'), RT_BITMAP) <> 0 then //Vérifie que la ressource existe bien
      begin
        try
          aBitmap.AlphaFormat := afDefined; //Nécessaire parce que la ressource est issue d'un PNG avec des infos Alpha
          aBitmap.LoadFromResourceName(HM, 'PluginImage'); //On charge la ressource proprement dite
        except
          Result := false;//Si ça plante, on retourne faux
        end;
      end else
        Result := false;//Si la ressource n'existe pas, on retourne faux
     
      FreeLibrary(HM);//Libération de la librairie
    end;
    C'est moins élégant mais au moins ça marche sans AV et sans memory leaks...

    Ceci dit si quelqu'un peut me dire pourquoi un TBiamp ne veut pas se détruire dans ce cas de figure, je suis preneur !
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    ShareMem permet de partager le gestionnaire de mémoire, mais pas les objets, le partage d'objet se fait uniquement avec des Packages

    mais ton plugin peu très bien retourner un HBitmap (THandle) comme dans le livre.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    ShareMem permet de partager le gestionnaire de mémoire, mais pas les objets, le partage d'objet se fait uniquement avec des Packages
    Ah? Pourtant, le fait de passer une classe en paramètre fonctionne très bien. Ca ne partage pas réellement un objet mais bon.
    De plus au moment où j'appelle la fonction de récupération des infos, le TBitmap existe déjà.
    Citation Envoyé par Paul TOTH Voir le message
    mais ton plugin peu très bien retourner un HBitmap (THandle) comme dans le livre.
    J'avais déjà regardé mais la méthode que j'utilise est sensiblement différente.

    D'ailleurs as-tu remarqué qu'une DLL faisant apparaître une TForm quel que soit son contenu laisse systématiquement un reliquat de mémoire très petit certes mais quand même.
    J'ai essayé toute sorte de méthode (appel simple, interface, passage de classe, etc.) pour la faire disparaître mais rien n'y fait:
    ---------------------------
    Unexpected Memory Leak
    ---------------------------
    An unexpected memory leak has occurred. The unexpected small block leaks are:

    109 - 116 bytes: Unknown x 1

    ---------------------------
    OK
    ---------------------------
    Merci en tout cas pour ton aide !
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par Pedro Voir le message
    Ah? Pourtant, le fait de passer une classe en paramètre fonctionne très bien. Ca ne partage pas réellement un objet mais bon.
    ça peut fonctionner avec exactement la même version de Delphi, exactement les mêmes sources et les mêmes options de compilations. Le problème est que l'exe et la dll ont chacun leur propre versions des méthodes de l'objet, donc si à l'octet près c'est le même objet, et que les deux utilisent ShareMem ça fonctionnera en effet. Mais une mise à jour de Delphi, ou du code d'un côté uniquement et c'est le GPF assuré.

    Citation Envoyé par Pedro Voir le message
    De plus au moment où j'appelle la fonction de récupération des infos, le TBitmap existe déjà.
    J'avais déjà regardé mais la méthode que j'utilise est sensiblement différente.
    non, ta ressource est un simple Bitmap 32bits, AlphaFormat est utilisé par l'objet TBitmap pour déterminer comment exploiter le canal Alpha existant (fonction AlphaBlend de l'API Windows) et tu peux donc très bien utiliser un HBitmap.

    Citation Envoyé par Pedro Voir le message
    D'ailleurs as-tu remarqué qu'une DLL faisant apparaître une TForm quel que soit son contenu laisse systématiquement un reliquat de mémoire très petit certes mais quand même.
    J'ai essayé toute sorte de méthode (appel simple, interface, passage de classe, etc.) pour la faire disparaître mais rien n'y fait:
    non, je n'utilise jamais de DLL, mais à priori il n'y a pas de raison d'avoir un reliquat si tu libères tout correctement.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    ça peut fonctionner avec exactement la même version de Delphi, exactement les mêmes sources et les mêmes options de compilations. Le problème est que l'exe et la dll ont chacun leur propre versions des méthodes de l'objet, donc si à l'octet près c'est le même objet, et que les deux utilisent ShareMem ça fonctionnera en effet. Mais une mise à jour de Delphi, ou du code d'un côté uniquement et c'est le GPF assuré.
    Effectivement vu comme ça... Ca remet pas mal en cause mon besoin de modularité... Donc dans un souci de modularité justement, il vaut mieux utiliser les packages dès que des classes sont passées en paramètre?
    Citation Envoyé par Paul TOTH Voir le message
    non, ta ressource est un simple Bitmap 32bits, AlphaFormat est utilisé par l'objet TBitmap pour déterminer comment exploiter le canal Alpha existant (fonction AlphaBlend de l'API Windows) et tu peux donc très bien utiliser un HBitmap.
    OK ce que je voulais dire c'est que le TBitmap était créé et ne se comportait pas comme les autres classes passées en paramètre.
    Citation Envoyé par Paul TOTH Voir le message
    non, je n'utilise jamais de DLL, mais à priori il n'y a pas de raison d'avoir un reliquat si tu libères tout correctement.
    C'est aussi ce que je croyais mais si tu as l'occasion de vérifier, tu devrais avoir le même "problème".
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Citation Envoyé par Pedro Voir le message
    Effectivement vu comme ça... Ca remet pas mal en cause mon besoin de modularité... Donc dans un souci de modularité justement, il vaut mieux utiliser les packages dès que des classes sont passées en paramètre?
    non il faut utiliser des Interfaces voir des objets COM...mais c'est en gros ce que j'explique dans mon livre hein.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    non il faut utiliser des Interfaces voir des objets COM...
    OK
    Citation Envoyé par Paul TOTH Voir le message
    mais c'est en gros ce que j'explique dans mon livre hein.
    Je retourne le potasser immédiatement
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  10. #10
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Citation Envoyé par Pedro Voir le message
    C'est aussi ce que je croyais mais si tu as l'occasion de vérifier, tu devrais avoir le même "problème".
    Pour la petite histoire, je viens de découvrir que ce reliquat est simplement dû à SimpleShareMem...
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 31/05/2010, 14h38
  2. Réponses: 5
    Dernier message: 08/09/2005, 20h33
  3. Contexte de chargement d'une DLL
    Par Guillemot dans le forum Windows
    Réponses: 2
    Dernier message: 10/07/2005, 09h34
  4. Comment charger un TFrame depuis une dll ?
    Par Millenod dans le forum Langage
    Réponses: 29
    Dernier message: 22/12/2004, 14h48
  5. Chargement d'une DLL et utilisation du multithread
    Par Maitre Kanter dans le forum Langage
    Réponses: 6
    Dernier message: 07/09/2004, 23h18

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