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++Builder Discussion :

Dll a chargement dynamique


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut Dll a chargement dynamique
    salut !!

    je susi en train de developper une application qui a fortement recour aux dlls, notamment pour le systeme de plugins.
    Cependant, je rencotre un probleme:

    1- avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    typedef AnsiString (__stdcall *GETINFOSONDLL)(void);
     
     HINSTANCE hinstDLL;
     GETINFOSONDLL ImpFuncDLL;
     
     hinstDLL = LoadLibrary("DLL/key.dll") ;
     if ( hinstDLL )
        ImpFuncDLL = (GETINFOSONDLL)GetProcAddress(hinstDLL, "GetDLLVersion");
     
     if (ImpFuncDLL)
       Application->MessageBoxA(ImpFuncDLL().c_str(),"",0);
     
      FreeLibrary(hinstDLL);
    hey bien ImpFuncDLL vaut null. Mais je ne comprend pas pourquoi : la DLL est bien chargée (elle affiche un msg) et GetDLLVersion est une fonction de ma DLL qui correspond a ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    AnsiString __stdcall GetDLLVersion()
    {
     AnsiString tmp = IntToStr(VERSION);
     return tmp;
    }
    De plus, j'ai suivi le tutorial de LFE et ne vosi aps ce que j'aurais sauté !

    merci.
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  2. #2
    Futur Membre du Club
    Inscrit en
    Juin 2003
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Tu peux obtenir plus d'info en utilisant GetLastError()
    Voilà un exemple de code pour obtenir un message en clair :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char MsgBuf[100];
    	FormatMessage(
    	    FORMAT_MESSAGE_FROM_SYSTEM,
        	NULL,
    	   	GetLastError(),
    	    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    	    MsgBuf,
    	    99,
    	    NULL
    		);
    Nicolas Gallerand

  3. #3
    Membre à l'essai
    Inscrit en
    Juillet 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 16
    Points : 22
    Points
    22
    Par défaut
    1) il est déconseillé de transférer des AnsiString via des DLL. Lire le message d'avertissement qui se crée automatiquement lorsqu'on crée une DLL:

    //---------------------------------------------------------------------------
    // Remarque importante concernant la gestion de mémoire de DLL lorsque votre DLL utilise la
    // version statique de la bibliothèque d'exécution :
    //
    // Si votre DLL exporte des fonctions qui passent des objets String (ou des
    // structures/classes contenant des chaînes imbriquées) comme paramètre
    // ou résultat de fonction, vous devrez ajouter la bibliothèque MEMMGR.LIB
    // à la fois au projet DLL et à tout projet qui utilise la DLL. Vous devez aussi
    // utiliser MEMMGR.LIB si un projet qui utilise la DLL effectue des opérations
    // new ou delete sur n'importe quelle classe non dérivée de TObject qui est
    // exportée depuis la DLL. Ajouter MEMMGR.LIB à votre projet forcera la DLL et
    // ses EXE appelants à utiliser BORLNDMM.DLL comme gestionnaire de mémoire.
    // Dans ce cas, le fichier BORLNDMM.DLL devra être déployé avec votre DLL.
    //
    // Pour éviter d'utiliser BORLNDMM.DLL, passez les chaînes comme paramètres "char *"
    // ou ShortString.
    //
    // Si votre DLL utilise la version dynamique de la RTL, vous n'avez pas besoin
    // d'ajouter MEMMGR.LIB, car cela est fait automatiquement.
    //---------------------------------------------------------------------------
    2) Il est également déconseillé d'utiliser _stdcall (je pensais même que c'était impossible). Sinon, ta DLL ne sera compatible qu'avec des programmes Borland.

    3) Si c'est une fonction C++, elle ne s'apelle pas GetDLLVersion, mais un truc comme @GetDLLVersion@iv@ (utilise ImpLib pour avoir son nom exact). Si ce n'est pas une fonction C++, il manque extern "C".

    4) Tant que tu y est, essaye aussi de rajouter le mot-clé _export...
    Il y a trois sortes d'informaticiens : ceux qui savent compter et ceux qui ne savent pas compter.

  4. #4
    Futur Membre du Club
    Inscrit en
    Juin 2003
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    2) Il est également déconseillé d'utiliser _stdcall (je pensais même que c'était impossible). Sinon, ta DLL ne sera compatible qu'avec des programmes Borland.
    Au contraire __stdcall est impératif pour être standard. C'est __fastcall qui est spécifique Borland.

    la déclaration de la fonction exportée doit être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    extern "C" __declspec(dllexport) AnsiString __stdcall GetDLLVersion(void)
    la même fonction importée doit être déclarée avec dllimport :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    extern "C" __declspec(dllimport) AnsiString __stdcall GetDLLVersion(void)
    La signature des fonctions exportée par une DLL Borland peut être vue facilement en utilisant Aperçu rapide (clic droit sur le fichier .DLL).
    Nicolas Gallerand

  5. #5
    Membre à l'essai
    Inscrit en
    Juillet 2002
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 16
    Points : 22
    Points
    22
    Par défaut
    Mille excuses ! T'as entièrement raison pour le _stdcall. C'est moi qui ai lu trop fast...
    Il y a trois sortes d'informaticiens : ceux qui savent compter et ceux qui ne savent pas compter.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    salut !

    dans le tutoriel de LFE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    extern "C" __declspec(dllexport) AnsiString __stdcall GetDLLVersion(void)
    c'est pou un appel statique, quand on a le dichier lib. Enfin, a ce que je crois.
    Sinon, je veux bien inclure MEMMGR.LIB, sauf que je ne l'ai pas !
    Ou le trouver ?

    merci.
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

  7. #7
    Futur Membre du Club
    Inscrit en
    Juin 2003
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    J'ai répondu un peu vite.
    C'est la déclaration dllimport qui est valable pour une liaison statique.

    La déclaration dllexport est la même dans les deux cas. Une fonction déclarée de manière ordinaire ne sera pas exportée : sa portée est limitée au code interne de la DLL.

    Ton code me parait correct sauf la déclaration de la fonction de la DLL.

    A mon avis, le problème de libération mémoire concernant les AnsiString disparaît si tu passes une référence au lieu de créer un objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ... AnsiString& GetDLLVersion(...)
    Je serais content d'avoir une confirmation sur ce point.
    Nicolas Gallerand

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Points : 121
    Points
    121
    Par défaut
    effectivement, le probleme venait bien de mon oublie : dire que la fonction doit etre exporté dans la dll...

    merci

    cependant, je n'ai pas compris le probleme de la fuite de mémoire resolvable par "&" ???

    merci.
    OS : WinXP
    Outils : VC++ 8 (Visual Studio 2005)

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

Discussions similaires

  1. [VB.NET] Chargement dynamique des dlls de l'application
    Par leSeb dans le forum Windows Forms
    Réponses: 3
    Dernier message: 27/01/2006, 17h49
  2. [Dll] Chargement dynamique a base d'index
    Par Clorish dans le forum Langage
    Réponses: 20
    Dernier message: 25/03/2005, 14h19
  3. [MFC VC.NET] Chargement dynamique de DLL
    Par vanitom dans le forum MFC
    Réponses: 3
    Dernier message: 26/01/2005, 13h56
  4. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20
  5. Chargement dynamique de DLL sous Unix
    Par Willou dans le forum Autres éditeurs
    Réponses: 7
    Dernier message: 18/12/2002, 18h25

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