Ajouter un commentaire

CeDreams

Tout d'abord, je vous remercie pour votre disponibilité, encore désolé pour le MP.

Ok, j'avais bien connaissance de ces conventions d'appel mais je pensais avoir compris que le protocole dont vous parliez concernait d'autres points que j'ignorai.

Je n'ai pas encore été explicite sur ce que je recherche alors je vais tenter de l'expliquer.

J'appelle à partir de Delphi une fonction de la DLL écrite en C++ par stdcall.
Cette fonction demande en paramètre une procédure et elle retourne immédiatement lors d'un appel un type DWORD en C++ donc un LongInt chez Delphi. Jusque-là pas de soucis particulier.

La procédure en paramètre sera appelée dans la DLL lors d'un passage d'un badge magnétique pour une identification de personne. Donc il y a un Thread qui tourne pour gérer l'attente du passage du badge.

Cette procédure en C++ attend deux paramètres, le 1er est un char *, le 2nd un int. Donc du côté Delphi, un PChar et un Integer et déclarée avec cdecl.

Lors du déclenchement de la procédure dans la DLL, cela remonte dans mon .exe Delphi qui affecte les deux paramètres à des variables locales de types string et Integer. Pour l'entier, ça ne doit pas poser de problème. Par contre, pour la chaîne de caractère, il me semble que je peux affecter un PChar à une string sans problème.

D'après mes dernières manipulations, c'est à l'accès des paramètres dans Delphi que je rencontre des soucis. L'entier est accessible mais me renvoie une valeur incohérente. Mais pire, l'accès à la chaîne me renvoie une erreur du type 'L'instruction à ... emploie l'adresse mémoire ... . La mémoire ne peut pas être "read"'. J'en conclus que j'ai un problème de compatibilité de mes variables/paramètres.

Voici un extrait de mon prog. de test avec Delphi.

type
  TMaFonction = procedure(szCodeIdent: PChar; nStatus: Integer); cdecl;

procedure MaFonction(szCodeIdent: PChar; nStatus: Integer);
begin
  Etat:= nStatus;
  if Etat = 0 then
    strCodePerso:= szCodeIdent;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
  HND: THandle;
  DLL_Start: function (fct: TMaFonction): LongInt; stdcall;
begin
  ResultStart:= 10;
  HND := LoadLibrary('XXX.dll');
  try
    If (HND >= 32) Then
    Begin
      @DLL_Start:= GetProcAddress(HND,'_Start@4');
      if @DLL_Start<> nil then
        ResultStart:= DLL_Start(@MaFonction)
      else
        MessageBox(0,'ERROR','NIL',MB_ICONERROR);
      End
    Else MessageBox(0,'ERROR','ERROR',MB_ICONERROR);
    Sleep(4000); // 4 sec. pour passer le badge
  finally
    FreeLibrary(HND);
  end;
end;

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 RRRR   H  H   GGG    CCC  ZZZZZ 
R R H H G C Z
RRRR HHHH G GG C Z
R R H H G G C Z
R RR H H GGG CCC ZZZZZ