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 :

EXE chargé comme DLL : comment savoir quel mode est utilisé


Sujet :

Langage Delphi

  1. #1
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut EXE chargé comme DLL : comment savoir quel mode est utilisé
    Salut a tous,
    j'ai un exe de qui me permet de concevoir des plans assez complexes, ou tout est assez lié entre l'IHM et les structures de données, qui ne me permet pas d'utiliser des structures externalisées dans une dll.
    D'autre part, j'ai un 2eme exe qui permet de générer les différents plans décrits par les données stockées dans un fichier généré par le 1er exe. Ce 2eme exe utilise une dll qui contient uniquement les structures du 1er exe (quasiment tout excepté l'IHM).
    J'ai donc actuellement un gros exe de conception, une petit exe de sélection des plans qui utilise un dll qui est un sous ensemble du gros exe.
    Ce que je voudrais faire, c'est d'utiliser l'exe à la place de la dll pour générer les plans. Seul petit problème, il y a des traitements qui doivent différer selon que l'exe soit exécuté pour faire de la conception ou qu'il soit utilisé comme dll.

    Il faudrait donc que je puisse savoir si je suis en mode exe ou dll. J'ai vu qu'il y a une variable IsLibrary, mais elle vaut false pour un exe chargé avec LoadLibrary.
    Connaissez vous un autre moyen qui me permettrai de savoir dans quel mode d'exécution je me trouve ?

    Merci

  2. #2
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    887
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 887
    Points : 1 531
    Points
    1 531
    Par défaut
    Je pense que lorsqu'on est dans une Dll, GetModuleHandle donne un résultat différent suivant qu'on fait GetmoduleHandle(NULL) ou bien GetModuleHandle(NomDeLaDll).

    Après, je ne sais pas si ça marche pour un EXE chargé avec LoadLibrary, c'est quand même un cas un peu particulier.

    Question bête: c'est pas possible d'appeler ton EXE avec des paramètres pour différentier les deux cas ?

  3. #3
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par 10_GOTO_10 Voir le message
    Question bête: c'est pas possible d'appeler ton EXE avec des paramètres pour différentier les deux cas ?
    Ca aurait été bien, mais je ne peux pas. En fait, le 1er exe n'est pas unique. J'ai plusieurs gros exe qui permettent de creer differents types de plans, et j'ai un petit exe qui, a partir d'un fichier, va demander aux gros exes lequel sait gerer ce fichier, et d'en generer des plans autocad.

    Mais c'est une très bonne piste que tu me donnes la. Le seul probleme, c'est que l'unité qui a besoin de savoir si elle est executée en mode dll ou exe est utilisée par les differents gros exes, donc je ne peux pas mettre en statique le nom du module.
    J'ai testé, ca marche bien, mais il faut juste que je trouve comment recuperer le nom du module courant. Voici le resultat de mes investigations sans succès :
    j'ai une unité avec une fonction TestExport qui est uses dans 2 projets : Project1 et Project3 et exportée par Project3 (qui prend donc le role de mon gros exe)
    je lance project1 et j'appele la fonction dans l'exe lui meme, ca me donne le bloc "Ajouté par self", puis je loadLib(Project3) et jappele la fonction, ca me donne le bloc "Ajouté par dll"
    Ajouté par self
    HND nil : 4194304
    HND "Project3.exe" : 0
    IsLibrary : False
    ModuleIsLib : False
    GetModuleName : C:\Program Files (x86)\Borland\Delphi7\Projects\Project1.exe
    MainInstance : 4194304
    HInstance : 4194304
    paramStr : C:\Program Files (x86)\Borland\Delphi7\Projects\Project1.exe

    Ajouté par dll
    HND nil : 4194304
    HND "Project3.exe" : 8388608
    IsLibrary : False
    ModuleIsLib : False
    GetModuleName : C:\Program Files (x86)\Borland\Delphi7\Projects\Project1.exe
    MainInstance : 4194304
    HInstance : 4194304
    paramStr : C:\Program Files (x86)\Borland\Delphi7\Projects\Project1.exe
    Donc la question qui subsiste est : Comment connaitre le nom du module courant ?


    Voici le code utilisé:
    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
     
    procedure TestExport(const AMsg: string; AMemo: TMemo);
    var
      sNom: string;
    begin
      sNom := ExtractFilePath(Application.ExeName) + 'Project3.exe';
     
      AMemo.Lines.Add(AMsg);
      AMemo.Lines.Add(' HND  nil : ' + IntToStr(GetModuleHandle(nil)));
      AMemo.Lines.Add(' HND "'+ExtractFileName(snom)+'" : ' + IntToStr(GetModuleHandle(PChar(snom))));
      AMemo.Lines.Add(' IsLibrary : ' + BoolToStr(IsLibrary, true));
      AMemo.Lines.Add(' ModuleIsLib : ' + BoolToStr(ModuleIsLib, true));
      AMemo.Lines.Add(' GetModuleName : ' + GetModuleName(0));
      AMemo.Lines.Add(' MainInstance : ' + IntToStr(MainInstance));
      AMemo.Lines.Add(' HInstance : ' + IntToStr(HInstance));
      AMemo.Lines.Add(' paramStr : ' + ParamStr(0));
      AMemo.Lines.Add('');
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      TestExport('Ajouté par self', Memo1);
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      hnd: THandle;
      p: TTestExport;
    begin
      hnd := LoadLibrary(PChar(ExtractFilePath(Application.ExeName) + 'Project3.exe'));
      p := GetProcAddress(hnd, 'TestExport');
      p('Ajouté par dll', Memo1);
      FreeLibrary(hnd);
    end;

  4. #4
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    887
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 887
    Points : 1 531
    Points
    1 531
    Par défaut
    Citation Envoyé par guillemouze Voir le message
    Donc la question qui subsiste est : Comment connaitre le nom du module courant ?
    Je dirais GetModuleFileNameEx(GetCurrentProcess(), NULL, ...). A tester.

  5. #5
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par 10_GOTO_10 Voir le message
    GetModuleFileNameEx(GetCurrentProcess(), NULL, ...). A tester.
    Et bien non, car le 2eme parametre a passer à GetModuleFileNameEx est le handle du module recherché, autrement dit ... le handle que je cherche a recuperer pour le comparer.
    Ca ferait l'egalité suivante :
    hModule = GetModuleHandle(GetModuleFileNameEx(GetCurrentProcess, hModule, buff, N));

    Une autre idée ? car je ne vois pas ou trouver les infos du module et non de l'exe du process. Tout ce que je test me renvoie "Project1" et je n'arrive pas à trouver une variable / fonction qui me retourne "Project3" ou son handle

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 549
    Points : 25 119
    Points
    25 119
    Par défaut
    Dommage que DLLEntryPoint en fonctionne qu'au second chargement de la DLL

    Ton loadLibrary est accompagné d'un GetProcAddr ?
    Pourquoi ne pas mettre un flag lors de l'appel des fonctions exportées ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ton loadLibrary est accompagné d'un GetProcAddr ?
    Pourquoi ne pas mettre un flag lors de l'appel des fonctions exportées ?
    oui il y a des GetProcAddr, sinon je vois pas trop l'interet du LoadLibrary ! (a part pour les ressources mais dans ce cas la il y a LaodLibraryEx)

    En fait, le probleme que j'ai, c'est que dans l'initialization de certaines unités, il y a des requetes dans une base de données. Hors CoInitialize ne fonctionne pas dans l'initialisation d'un dll -> donc je ne peux pas faire ces actions si je charge mon exe par un LoadLibrary.
    Le flag setté a l'appel des fonctions exportées arriverait trop tard, l'initialization aurait deja ete faite A moins que je n'ai pas compris ce que tu voulais dire Shai

    Dommage que DLLEntryPoint en fonctionne qu'au second chargement de la DLL
    En parlant de ca, le code entre le begin/end de mon dpr n'est pas executé quand je le charge en dll. Ce qui voudrait dire que ce code est appelé au demarrage de l'exe (WinMain ou un truc dans le genre), mais pas comme DllMain comme le serait le code d'une dll classique ?
    Donc peut etre pourrais-je mettre du code qui s'executerai en tant que DllMain, mais comment ... ?

  8. #8
    Membre expérimenté Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    887
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 887
    Points : 1 531
    Points
    1 531
    Par défaut
    Citation Envoyé par guillemouze Voir le message
    Et bien non, car le 2eme parametre a passer à GetModuleFileNameEx est le handle du module recherché, ...
    Read The Fantastic Manuel:

    hModule [in, optional]
    A handle to the module. If this parameter is NULL, GetModuleFileNameEx returns the path of the executable file of the process specified in hProcess.

  9. #9
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    ah je savais pas que c'etait fantastic et je l'ai bien lu.
    returns the path of the executable file of the process specified in hProcess
    seulement GetCurrentProcess(), hInstance, mainInstance retournent le handle du process, hors une dll apparient au meme process que l'application (un seul fil d'execution), et j'ai testé ave NULL, ca me retourne effectivement le nom de l'exe principal. Il faut donc bien que je passe un handle de module, et celui-ci est precisement celui que je cherche a obtenir au final !

    Peut-etre avez vous une autre piste ?
    En tout cas merci pour l'aide apportée jusqu'a présent

Discussions similaires

  1. Comment savoir quel radiobutton est coché dans un groupbox
    Par valebl dans le forum Windows Forms
    Réponses: 12
    Dernier message: 09/06/2008, 19h40
  2. Réponses: 1
    Dernier message: 03/04/2008, 11h08
  3. Comment savoir quel radiobutton est sélectionné ?
    Par eaglesnipe dans le forum C#
    Réponses: 4
    Dernier message: 21/02/2008, 09h44
  4. Réponses: 3
    Dernier message: 22/02/2006, 11h23
  5. comment savoir quel menu est en surbrillance?
    Par LRobi dans le forum MFC
    Réponses: 2
    Dernier message: 27/01/2005, 09h04

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