Pb DLL

Signaler
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012
-
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012
-
salut a tous
j'ai realiser un soft et une dll. lorsque je lance mon soft il fonctionne bien avec la dll.
Mais lorsque je le ferme il m 'indique operation de pointer incorrecte. J'ai recherche la solution parmis les soft depose mais je trouve pas le pb.

pourtant mes declaration sont correcte. j'ai regarder parmis ces soft et c'est les memes declaration que j'ai inserer.

merci d'avance a tous

 neo

Neo [OSOK]

17 réponses

Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut a tous je met mon source de ma dll a disposition elle sert a recuperer la version d'un exe

library Param;


{ Remarque importante concernant la gestion de mémoire de DLL : ShareMem doit
  être la première unité de la clause USES de votre bibliothèque ET de votre projet
  (sélectionnez Projet-Voir source) si votre DLL exporte des procédures ou des
  fonctions qui passent des chaînes en tant que paramètres ou résultats de fonction.
  Cela s'applique à toutes les chaînes passées de et vers votre DLL --même celles
  qui sont imbriquées dans des enregistrements et classes. ShareMem est l'unité
  d'interface pour le gestionnaire de mémoire partagée BORLNDMM.DLL, qui doit
  être déployé avec vos DLL. Pour éviter d'utiliser BORLNDMM.DLL, passez les
  informations de chaînes avec des paramètres PChar ou ShortString. }


uses
   ShareMem,Windows, SysUtils, Classes;


{$R *.res}


function DonneVersion : ShortString ;
var
  VerInfoSize, VerValueSize,
  Dummy      : DWORD;
  VerValue   : PVSFixedFileInfo;
  VerInfo    : Pointer;
  Version    : string;
  Exe : string;
  Resultat : string;
begin
  Exe:='..\\WinNeo.exe';


  try
    Version := ('0.0.0');
    //VerInfoSize := GetFileVersionInfoSize(PChar(Application.ExeName),
    VerInfoSize := GetFileVersionInfoSize(PChar(Exe),
Dummy);
    GetMem(VerInfo, VerInfoSize);
    if VerInfo <> nil then
    begin
      //GetFileVersionInfo(PChar(Application.ExeName), 0, VerInfoSize,
      GetFileVersionInfo(PChar(Exe), 0, VerInfoSize,
VerInfo);
      VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
      with VerValue^ do
      begin
        {Version := Format('%d.%d.%d.%d',
                         [dwFileVersionMS shr 16, dwFileVersionMS and
$FFFF,
                          dwFileVersionLS shr 16, dwFileVersionLS and $FFFF
]);}
        Version := Format('%d.%d.%d', [dwFileVersionMS shr 16,
dwFileVersionMS and $FFFF,
                                       dwFileVersionLS and $FFFF ]);
      end; { with }
      FreeMem(VerInfo, VerInfoSize);
    end; { if }
    result := Version;
  except on E : Exception do
  DonneVersion:=Version;
  end;   { except }
end; { function TfmMain.RecupVersionSoft }


 




    exports DonneVersion;
end.

et je vais mettre
ce que j'ai mis dans mon soft

{$R *.dfm}




// DLL gestion des Parametre
    function DonneVersion() : ShortString; external 'DLL\\Param.dll'

puis je l'appelle un un moment et des que je ferme le programme il me met operation de pointer incorrecte. donc si quelqu'un trouve l'erreur je serait tres heureux

merci pour votre aide

Neo [OSOK]
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Salut,

Tu peux virer l'uses de ShareMem comme tu utilises un ShortString.

Je comprend pas ta ligne : DonneVersion:=Version;

Tu peux me l'expliquer s'il te plait ?
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

Salut, je te remercie pour ton aide
Au debut je n'avais pas mis le shortString mais string et je n'avais pas mis n'ont plus Sharemem.
je recupere la version et je la stocke dans Version et a la fin ja la met a DonneVersion.

merci

Neo [OSOK]
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Donc ça marche pas mieux sans ShareMem ?

ShareMem, ça sert à remplacer l'alloueur/désalloueur de mémoire de l'exe et de la dll par un alloueur/désalloueur commun à l'exe et la dll.

Si on utilise pas ShareMem, tout ce qui est alloué dans l'exe ne peut être désalloué dans la dll, et tout ce qui est alloué dans la dll ne peut être désalloué dans l'exe (Un gestionnaire ne peut pas désallouer ce qu'il n'a pas allouer). L'alloueur de l'exe ou de la dll n'est pas utilisé lorsque l'on utilise des routines de l'OS genre GlobalAlloc, SysAllocString... Avec ces routines, ont peut effectivement faire des allocation/libération côté exe et dll sans problème. Mais lorsque l'on utilise GetMem, New ou des String (Qui sont très souvent réallouées, par exemple lors d'une concaténation, d'une recopie...), c'est le gestionnaire de mémoire de Delphi qui est appelé (Il est a priori plus rapide que GlobalAlloc, et ne fait appel à lui que pour récupérer des blocs).

Mais ShareMem est pas mal critiqué : par exemple la dll devient inutilisable depuis un exe d'un autre langage (Vu que l'on ne peut pas mettre ShareMem dans les uses en VB ou en C...) Il est aussi plutôt lent paraît-il. Bref, il est souvent préférable de s'en passer...

je recupere la version et je la stocke dans Version et a la fin ja la met a DonneVersion.

Version est une chaîne de caractère de type String, on est d'accord... Mais DonneVersion, c'est une fonction. Comment peut tu affecter une chaîne de caractère à une fonction ?

C'est équivalent à faire un Result:= Version; ?
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Bonjour,

rt15, le résultat d'une fonction peut être affecté de deux façon, soit en utilisant le nom de la dite fonction soit en utilisant Result.

function MaFonction : boolean;
begin
  MaFonction:=true; // Equivaut à Result:=true;
end ;

Neo, englobe l'utilisation de VerInfo par un try..finally pour être sur de désallouer le pointeur. Actuellement, si une exception se produit, tu ne libères jamais ce pointeur.

Getmem
try
...
finally
  freemem
end;

Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut
et merci pour cette info je vais essayer et je te redirai ça .

amicalement

Neo [OSOK]
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut
j'ai essaye ce que tu m'as dis, mais je crois que je l'integre mal je te met ce que j'ai fais et tu verra mais en tout cas j'ai toujours le meme probleme

library Param;


{ Remarque importante concernant la gestion de mémoire de DLL : ShareMem doit
  être la première unité de la clause USES de votre bibliothèque ET de votre projet
  (sélectionnez Projet-Voir source) si votre DLL exporte des procédures ou des
  fonctions qui passent des chaînes en tant que paramètres ou résultats de fonction.
  Cela s'applique à toutes les chaînes passées de et vers votre DLL --même celles
  qui sont imbriquées dans des enregistrements et classes. ShareMem est l'unité
  d'interface pour le gestionnaire de mémoire partagée BORLNDMM.DLL, qui doit
  être déployé avec vos DLL. Pour éviter d'utiliser BORLNDMM.DLL, passez les
  informations de chaînes avec des paramètres PChar ou ShortString. }


uses
   ShareMem,Windows, SysUtils, Classes;


{$R *.res}


function DonneVersion : String ;
var
  VerInfoSize, VerValueSize,
  Dummy      : DWORD;
  VerValue   : PVSFixedFileInfo;
  VerInfo    : Pointer;
  Version    : string;
  Exe : string;
begin
  Exe:='.\\WinNeo.exe';
  GetMem(VerInfo, VerInfoSize);
  try
    try
      Version := ('0.0.0');
      VerInfoSize := GetFileVersionInfoSize(PChar(Exe),Dummy);
      if VerInfo <> nil then
       begin
        GetFileVersionInfo(PChar(Exe), 0, VerInfoSize,VerInfo);
        VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);


        with VerValue^ do
        begin
          Version := Format('%d.%d.%d', [dwFileVersionMS shr 16,
          dwFileVersionMS and $FFFF,dwFileVersionLS and $FFFF ]);
        end; { with }
       end; { if }
      result := Version;
      //FreeMem(VerInfo, VerInfoSize);
      except on E : Exception do
       DonneVersion:=Version;
      end;  { except }
  finally
  FreeMem(VerInfo, VerInfoSize);
  end;
  end;
  exports DonneVersion;
end.

merci

Neo [OSOK]
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Ton code présente deux problèmes :
   Appel à GetMem(VerInfo, VerInfoSize) avec VerInfoSize non initialisé 
  Une exception peut se déclencher hors du bloc try..finally.

J'ai essayé avec ça, et à priori (chez moi ) pas de problèmes :




function DonneVersion : String ;
var
  VerInfoSize, VerValueSize,
  Dummy      : DWORD;
  VerValue   : PVSFixedFileInfo;
  VerInfo    : Pointer;
  Version    : string;
  Exe : string;
begin
  Exe:='.\\WinNeo.exe';
  try
    Version := ('0.0.0');
    VerInfoSize := GetFileVersionInfoSize(PChar(Exe),Dummy);
    GetMem(VerInfo, VerInfoSize);
    try
      if VerInfo <> nil then
      begin
        GetFileVersionInfo(PChar(Exe), 0, VerInfoSize,VerInfo);
        VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
        with VerValue^ do
        begin
          Version := Format('%d.%d.%d', [dwFileVersionMS shr 16,
          dwFileVersionMS and $FFFF,dwFileVersionLS and $FFFF ]);
        end; { with }
       end; { if }
      result := Version;
    finally
      FreeMem(VerInfo, VerInfoSize);    //FreeMem(VerInfo, VerInfoSize);
    end;
  except
    on E : Exception do
      DonneVersion:=Version;
  end;  { except }
end; exports DonneVersion;



Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Lol après une courte reflexion, je dirais plutôt :

function DonneVersion : String ;
var
  VerInfoSize, VerValueSize,
  Dummy      : DWORD;
  VerValue   : PVSFixedFileInfo;
  VerInfo    : Pointer;
  Version    : string;
  Exe : string;
begin
  Exe:='.\\WinNeo.exe';
  Result := '0.0.0';
  VerInfoSize := GetFileVersionInfoSize(PChar(Exe),Dummy);
  GetMem(VerInfo, VerInfoSize);
  try
    if VerInfo <> nil then
    begin
      GetFileVersionInfo(PChar(Exe), 0, VerInfoSize,VerInfo);
      VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
      with VerValue^ do
      begin
        Result := Format('%d.%d.%d', [dwFileVersionMS shr 16,
        dwFileVersionMS and $FFFF,dwFileVersionLS and $FFFF ]);
      end; { with }
     end; { if }
  finally
    FreeMem(VerInfo, VerInfoSize);    //FreeMem(VerInfo, VerInfoSize);
  end;
end; exports DonneVersion;

Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
(Merci pour les infos sur la syntaxe)

Pour ton plantage en fin de programme, j'ai fait des éssais et j'ai eu le même car je n'avais pas relu en détail le paragraphe.

ShareMem doit être la première unité de la clause USES de votre bibliothèque ET de votre projet (sélectionnez Projet-Voir source).

Il faut mettre ShareMem en uses en première position dans l'unité du projet (Accessible nottament via le menu Projet-Voir source)

Par contre, la récupération de la version ne donnait semble-t-il rien de bon chez moi.

A la place du '\', on peut peut être passer : '\\StringFileInfo\\040C04E4\\FileVersion'

Je vais réassayer ce soir...
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut

moi je vais essaye aussi de mon cote, car j'ai auusi un petit souci avec mon programme WinNeo pas mechant mais pb bizarre.

amicalement

Neo [OSOK]
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Je comprends pas vos problèmes de plantage, car comme je l'ai dit pas de soucis de mon côté (avec le code corrigé comme indiqué précédemment). Quelles versions de Delphi utilisez-vous tous les deux ?

Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut moi j'utilise la version 7 mais a prt le probleme de dll, l'autre pb que j'ai c'est rien du tout.

et toi tu utilise qu'elle version

amicalement

Neo [OSOK]
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
7 ito.
Pour avoir le plantage, j'ai mis ShareMem dans les uses de la dll, dans les uses de unit1 qui était l'unité de la form de mon exe, et j'ai oublié de le mettre dans les uses de l'unité du projet (le .dpr)
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Bon, après analyse j'avais laissé le code DonneVersion  dans le projet, d'où le fait que cela fonctionnait

Alors pour s'affranchir de tous les problèmes (utilisation de ShareMem, Incompatibilité d'appel à partir d'autres langages, etc...) la solution la plus simple est la suivante :

Code pour la DLL param :

library Param;




uses
  SysUtils,
  Windows;





{$R *.res}





const
  Exe ='.\\WinNeo.exe';





function DonneVersion :
PChar
; stdcall;
var
  VerInfoSize, VerValueSize,
  Dummy      : DWORD;
  VerValue   : PVSFixedFileInfo;
  VerInfo    : Pointer;
begin
  Result := '0.0.0';
  VerInfoSize := GetFileVersionInfoSize(Exe,Dummy);
  GetMem(VerInfo, VerInfoSize);
  try
    if VerInfo <> nil then
    begin
      GetFileVersionInfo(Exe, 0, VerInfoSize,VerInfo);
      VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
      with VerValue^ do
      begin
        Result := Pchar(Format('%d.%d.%d', [dwFileVersionMS shr 16,
        dwFileVersionMS and $FFFF,dwFileVersionLS and $FFFF ]));
      end; { with }
     end; { if }
  finally
    FreeMem(VerInfo, VerInfoSize);    //FreeMem(VerInfo, VerInfoSize);
  end;
end;





exports
  DonneVersion name 'DonneVersion';





begin
end.



Code d'appel de la DLL :

function DonneVersion() : PChar; stdcall; external 'Param.dll'

Exemple d'utilisation avec sous forme de string :

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := String(DonneVersion);
end;

En résumé, suppression de TOUS les appels ShareMem et passage des string en PChar

Cordialement. <hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Arf, bin moi j'ai tout passé en String avec ShareMem obligatoire.

J'ai juste viré le VerInfo <> nil qui ne sert pas à grand chose car GetMem (Contrairement à malloc) déclenche une exception en cas d'échec de l'allocation.
Je gère pas celle-ci : si l'OS ne peut plus fournir de mémoire le fait que le programme plante est un détail...
J'ai remplacé la ShortString de résultat par une String, et j'ai fait passer le nom du fichier en paramètre.
Si le fichier n'existe pas ou n'a pas d'infos de version, GetFileVersionInfoSize renvoie 0.

===============================================================
library Param;

uses
  ShareMem, Windows, SysUtils;

{$R *.res}

function DonneVersion(sFileName: String): String;
var
  uVerInfo: Pointer;               // Pointe sur une copie des infos de version
  uVerValue: PVSFixedFileInfo;     // Pointe sur les infos fixes
  nSize: Cardinal;                 // Récup des différentes tailles
begin
  Result:= '0.0.0.0';

  // Récupération de la taille des infos de version
  nSize:= GetFileVersionInfoSize(PChar(sFileName), nSize);
  if nSize = 0 then Exit;

  GetMem(uVerInfo, nSize);
  try
    // Récupération des infos de version
    if GetFileVersionInfo(PChar(sFileName), 0, nSize, uVerInfo) then
      // Récupération d'un pointeur sur les infos fixes
      if VerQueryValue(uVerInfo, '\', Pointer(uVerValue), nSize) then
        with uVerValue^ do
          Result:= Format('%d.%d.%d.%d', [
                   dwFileVersionMS shr 16,       // Majeure : 16 bits MSb de MS
                   dwFileVersionMS and $FFFF,    // Mineure : 16 bits LSb de MS
                   dwFileVersionLS shr 16,       // Release : 16 bits MSb de LS
                   dwFileVersionLS and $FFFF]);  // Build : 16 bits LSb de LS
  finally
    FreeMem(uVerInfo);
  end;
end;

exports
  DonneVersion;

end.
Messages postés
11
Date d'inscription
vendredi 5 janvier 2007
Statut
Membre
Dernière intervention
10 novembre 2012

salut
moi aussi j'avais mis sharemem dans la librairie et l'exe mais pas dans le projet.
Au debut javais mis ce code dans une fonction dans le projet. mais quand j'ai voulu le mettre dans une librairis plantage. merci a vous deux.

Neo [OSOK]