Erreur EAccessViolation à l'utilisation d'un DLL

Résolu
nielsen_design Messages postés 10 Date d'inscription mercredi 1 novembre 2000 Statut Membre Dernière intervention 19 juin 2009 - 8 mars 2007 à 14:36
 Utilisateur anonyme - 8 mars 2007 à 23:30
Bonjour,

j'ai le message d'erreur suivant lors de l'éxécution du programme de test de ma DLL : " Exception EAccessViolation dans le module GetIpAddress.dll dans 00008599. Violation d'accès à l'adresse 00338599 dans le module 'GetIpAddress.dll'. Lecture de l'adresse 0000000C. ".

Voici le code de ma DLL :

library GetIpAddress;


uses SysUtils, Winsock;


{$R *.res}


function GetMyIpAddress(HostName: PChar): PChar; stdcall;
var
  WSAData: TWSAData;
  WSAHost: PHostEnt;
begin
// Demarrage du gestionnaire de socket (WinSocks)
  WSAStartup($0001, WSAData);


// Récupération des information sur l'ordinateur (dont l'adresse IP)
  WSAHost := GetHostByName(HostName);
  Result := PChar(Format('%d.%d.%d.%d', [
                         Byte(WSAHost^.h_addr^[0]),
                         Byte(WSAHost^.h_addr^[1]),
                         Byte(WSAHost^.h_addr^[2]),
                         Byte(WSAHost^.h_addr^[3])
                         ]));

// Fermeture du gestionnaire de socket (WinSocks)
  WSACleanup;
end;


exports
GetMyIpAddress name 'GetMyIpAddress';


begin
end.

Et voici le code source de mon application de test :

program GetIpAddressTest;


{$APPTYPE CONSOLE}
{$R *.res}


uses Dialogs, SysUtils;


function GetMyIpAddress(HostName: PChar): PChar; stdcall; external 'GetIpAddress.dll' name 'GetMyIpAddress';


var
  HostName: String;
  IpAddress: String;
begin
  HostName := '';
  IpAddress := String(GetMyIpAddress(PChar(HostName)));


  Write('HostName := ' + HostName + #13#10 +
        'IpAddress := ' + IpAddress + #13#10 +
        'Appuyez sur une touche pour continuer...');
  ReadLn;
end.

Je pensait avoir fait les choses correctement en évitant d'utiliser des string en paramètres. Malheureusement celà ne semble toujours pas fonctionner. Je n'arrive pas à comprendre pourquoi. Et, de par le fait, comment résoudre ce problème.

Merci par avance à tous ceux qui pourrons m'apporter de l'aide à ce sujet.

Cordialement,
Dominique.

5 réponses

sylvunix Messages postés 93 Date d'inscription mardi 11 avril 2006 Statut Membre Dernière intervention 4 mars 2009
8 mars 2007 à 14:54
Salut,

A la première lecture, je vois déjà un point choquant.

Tu utilises la variable HostName dans GetMyIpAdress. Le fait que son type soit String ne signifie par qu'il y ait 255 caractères alloués en mémoire. Lorsque ta dll va écrire dans cette zone, il y aura forcément un problème.

Pour tester rapidement, avant l'adresse à ta dll, tu pourrais essayer d'ajouter la ligne HostName := 'XXX.XXX.XXX.XXX';

Sinon je te conseillerais plutôt d'utiliser un PChar à la place d'un String et de gérer toi-même l'allocation mémoire.
3
Utilisateur anonyme
8 mars 2007 à 15:09
Salut à tous,

@Sylvunix : "Le fait que son type soit String ne signifie par qu'il y ait 255 caractères alloués en mémoire."

Fais le test suivant : Met un Edit et un bouton sur une forme.

procedure TForm1.Button1Click(Sender: TObject);
Var
a:string;
b:boolean;
begin
b:=True;
a:='';
while b<>False Do
  Begin
  a:=a+'S';
  Edit1.Text:=IntToStr(length(a));
  sleep(50);
  application.ProcessMessages;
  End;
end;

Un string n'est pas limité à 255 caractères loin de là.

L'IDE fait que tu ne peux pas écrire plus de 255 caractères sur une ligne mais il y a une parade .
3
sylvunix Messages postés 93 Date d'inscription mardi 11 avril 2006 Statut Membre Dernière intervention 4 mars 2009
8 mars 2007 à 15:28
Francky23012301,

La valeur 255 est un reste du Turbo Pascal !

Fais le test suivant :

procedure TForm1.Button1Click(Sender: TObject);
var Hostname: String;
begin
  Hostname[5] := 'A';
end;

Ce que je voulais dire dans mon message est le fait que déclarer une variable de type string m'implique pas qu'un espace lui soit réservé !
3
nielsen_design Messages postés 10 Date d'inscription mercredi 1 novembre 2000 Statut Membre Dernière intervention 19 juin 2009
8 mars 2007 à 16:09
Merci à tous pour votre aide... Mais en regroupant les quelques neurone de valide qu'il me reste encore, voici ce à quoi je suis arriver :

-- Code de la DLL --

function GetMyIpAddress(HostName: PChar): PChar; stdcall;
var
  WSAData: TWSAData;
  WSAHost: PHostEnt;
begin
// Demarrage du gestionnaire de socket (WinSocks)
  WSAStartup(2, WSAData);


// Récupération des informations de socket (dont l'adresse IP)
  WSAHost := GetHostByName(HostName);
  Result := PChar(Format('%d.%d.%d.%d', [
                         Byte(WSAHost^.h_addr^[0]),
                         Byte(WSAHost^.h_addr^[1]),
                         Byte(WSAHost^.h_addr^[2]),
                         Byte(WSAHost^.h_addr^[3])
                         ]));


// Fermeture du gestionnaire de socket (WinSocks)
  WSACleanup;
end;

-- Code du Programme de Test --

function GetMyIpAddress(HostName: PChar): PChar; stdcall; external 'GetIpAddress.dll' name 'GetMyIpAddress';

function GetIpAddressString(HostName: String): String;
begin
  Result := String(GetMyIpAddress(PChar(HostName)));
end;

var
  HostName: String;
  IpAddress: String;
begin
  HostName := '';
  IpAddress := GetIpAddressString(HostName);


  Write('HostName := ' + HostName + #13#10 +
        'IpAddress := ' + IpAddress + #13#10 +
        'Appuyez sur une touche pour continuer...');
  ReadLn;
end.
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
8 mars 2007 à 23:30
@[auteurdetail.aspx?ID=745051 sylvunix]  : j'avais compris que tu avais compris . J'ai justre profiter de l'occasion pour souligner une erreur courante sur le web .

@+
0
Rejoignez-nous