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 :

Problème de chemin vers des fichiers avec une dll


Sujet :

C++

  1. #1
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut Problème de chemin vers des fichiers avec une dll
    Bonjour,

    je suis en train de développer une dll sous Visual Studio (express 2013), que j'intègre ensuite en tant que plugin dans une autre application.
    J'ai besoin de quelques fichiers externes (images, fichiers de configuration). Dans mon code, j'ai simplement besoin de récupérer le chemin vers ces fichiers (pas besoin de connaître leur contenu).

    Quel est le meilleur moyen de gérer ces fichiers lors du déploiement de mon application? J'aimerais bien fournir ma dll dans un dossier qui contiendrai également mes fichiers externes. Ainsi l'utilisateur aurait simplement à copier le dossier dans l'emplacement de son choix puis de charger le fichier dll à partir de l'application hôte.

    Pour le moment cela ne fonctionne pas. J'ai mis les chemins en relatif dans mon code, mais les fichiers ne sont pas trouvés au cours de l'exécution de mon programme. En effet le répertoire de référence est alors l'emplacement de l'application hôte et non l'emplacement de ma dll.

    Comment faire?
    Merci d'avance pour votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour des chemins relatifs à l'emplacement de la DLL, le mieux serait d'utiliser directement les fonctions qui donnent le chemin d'une DLL:
    • Dans le DLL_PROCESS_ATTACH, mémoriser le HMODULE dans une variable globale.
    • Lors que tu as besoin du chemin, tu passe ce HMODULE à GetModuleFileName()
    • Puis tu manipules le chemin pour remplacer le nom de la DLL par le nom du fichier que tu cherches.

    Note: Traditionnellement, il suffisait d'un buffer de taille MAX_PATH pour être sûr d'avoir la place pour le chemin de fichier. Depuis des changements récents, ce n'est plus garanti, et tu peux avoir besoin d'un buffer allant jusqu'à 32768 caractères. Un vector du type approprié remplit très bien ce rôle (et il marche quelle que soit la version de C++, contrairement à string::data()).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Bonjour,

    merci de cette réponse, en revanche je ne sais pas comment mettre en œuvre ta solution car c'est la première fois que je développe une dll et je ne suis pas familière des DLL_PROCESS_ATTACH, HMODULE etc.

    D'après ce que j'ai vu il faut avoir une fonction DllMain mais pour ma part elle n'est pas définie dans mon code. En effet j'ai créé un projet DLL vierge sous Visual Studio puis j'ai utilisé les fonctionnalités de l'API fournie par le constructeur du logiciel (le logiciel dans lequel j'intègre ma DLL en tant que plugin).

    Peux tu m'indiquer plus en détail comment faire ?
    Merci d'avance.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Tant que l'API du constructeur du logiciel hôte ne crée pas de DllMain() pour toi, ce n'est pas un problème.
    En gros, tu as besoin de ça pour mémoriser le hModule:
    Code C : 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
    HMODULE g_hModuleDeMaDll;
     
    BOOL WINAPI DllMain(
      _In_ HINSTANCE hinstDLL,
      _In_ DWORD     fdwReason,
      _In_ LPVOID    lpvReserved
    )
    {
    	if(fdwReason == DLL_PROCESS_ATTACH)
    		g_hModuleDeMaDll = hinstDLL;
    	return TRUE;
    }
     
    //Retourne le chemin du dossier de la DLL (backslash inclus) dans le buffer passé en paramètre.
    //En situation normale, un buffer de taille MAX_PATH devrait suffire.
    BOOL GetCheminDossierDll(LPTSTR buffer, DWORD bufferLength)
    {
    	DWORD lng = GetModuleFileName(g_hModuleDeMaDll, buffer, bufferLength);
    	if(lng == bufferLength) //Buffer trop petit
    		return FALSE;
    	if(FAILED(PathCchRemoveFileSpec(buffer, bufferLength))
    		return FALSE;
    	return TRUE;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Merci beaucoup pour ce code!
    J'ai pu le rajouter dans mon programme, cela compile mais au moment d'utiliser ma dll dans le logiciel hôte j'ai une exception, le message est le suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "Exception in QApplication::notify(). exception - Unkown exception. Receiver - Class: QMenu; Name: menuPlug_in_Tools
    Sachant que le menu "Plugin Tools" est le menu du logiciel hôte partir duquel j'exécute mon programme.
    C'est l'appel à la fonction "GetModuleFileName" qui génère cette exception.

    Malheureusement ce code n'a donc pas l'air de fonctionner dans mon cas particulier. En revanche j'ai découvert l'existence de la variable globale "_pgmptr" qui me fournit le chemin absolu vers mon logiciel hôte. Je peux me débrouiller avec ça, s'il n'y a pas d'autre moyen.

    Merci!

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    Réponse très tardive.

    Vous pouvez déboguer votre Dll en configurant VS pour qu'il lance votre application hôte.
    Il faudra aussi configurer votre débogueur pour qu'il prenne la main dès l'envoi de l'exception, avant que QApplication ne la catche.

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

Discussions similaires

  1. Distribuer des fichiers avec une application
    Par srvremi dans le forum Android
    Réponses: 5
    Dernier message: 26/01/2011, 17h40
  2. Copier des fichiers avec une contrainte de date
    Par jejeapollo dans le forum VBScript
    Réponses: 1
    Dernier message: 02/07/2009, 10h43
  3. Lister/supprimer des fichiers avec une extension précise
    Par guiguiomr dans le forum VBScript
    Réponses: 10
    Dernier message: 20/05/2008, 11h34
  4. [Conception] Lister des fichiers avec une URL
    Par dontDeleteMe dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 20/03/2007, 09h16
  5. |VB6] Comment Lister les liens vers des fichiers d'une page web
    Par Mayti4 dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 18/01/2005, 19h17

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