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 :

[DLL] Problème de récupération et d'utilisation d'une chaine de caractères


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2004
    Messages : 18
    Points : 12
    Points
    12
    Par défaut [DLL] Problème de récupération et d'utilisation d'une chaine de caractères
    Bonjour,

    voilà j'utilise une fonction d'une DLL qui me retourne un "char *" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* GetErrorString(long int lErrorNumber)
    J'ai déclaré la fonction comme suis sous Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function get_error_string(error_number: Int64): PChar; cdecl; external 'madll.dll' name 'GetErrorString'
    Le problème c'est que dès que je commence à utiliser la chaîne retournée je me tape des access violation dans tous les sens
    Ci-joint le code que j'utilise :
    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
     
    procedure ReturnGANG430ErrorMessageInStatusMemo(result_code: Int64);
    var
      p_error_message: PChar;
      error_message: String;
      taille: Integer;
    begin
      try
        GetMem(p_error_message, 256);
        p_error_message := get_error_string(result_code);
        StrLCopy(PChar(error_message), p_error_message, StrLen(p_error_message));
        Self.memo_etat.Lines.Add(error_message);
      finally
        FreeMem(p_error_message);
      end;
    end;
    Bon ca doit certainement être gros comme un paquebot mon erreur mais là j'avoue que je sèche...
    Merci d'avance pour vos réponses et avis éclairés !

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Frank38 Voir le message
    Bonjour,

    voilà j'utilise une fonction d'une DLL qui me retourne un "char *" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* GetErrorString(long int lErrorNumber)
    J'ai déclaré la fonction comme suis sous Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function get_error_string(error_number: Int64): PChar; cdecl; external 'madll.dll' name 'GetErrorString'
    Le problème c'est que dès que je commence à utiliser la chaîne retournée je me tape des access violation dans tous les sens
    Ci-joint le code que j'utilise :
    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
     
    procedure ReturnGANG430ErrorMessageInStatusMemo(result_code: Int64);
    var
      p_error_message: PChar;
      error_message: String;
      taille: Integer;
    begin
      try
        GetMem(p_error_message, 256);
        p_error_message := get_error_string(result_code);
        StrLCopy(PChar(error_message), p_error_message, StrLen(p_error_message));
        Self.memo_etat.Lines.Add(error_message);
      finally
        FreeMem(p_error_message);
      end;
    end;
    Bon ca doit certainement être gros comme un paquebot mon erreur mais là j'avoue que je sèche...
    Merci d'avance pour vos réponses et avis éclairés !
    bonjour, la fonction RETOURNE un pointeur, il n'est donc pas ici question d'allouer de la mémoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure ReturnGANG430ErrorMessageInStatusMemo(result_code: Int64);
    var
      p_error_message: PChar;
      error_message: String;
    begin
      p_error_message := get_error_string(result_code);
    //  StrLCopy(PChar(error_message), p_error_message, StrLen(p_error_message));
     error_message:=p_error_message;
     Self.memo_etat.Lines.Add(error_message);
    end;
    attention aussi à la convention d'appel, cdecl ou stdcall...là ça dépend de la DLL.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2004
    Messages : 18
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    bonjour, la fonction RETOURNE un pointeur, il n'est donc pas ici question d'allouer de la mémoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure ReturnGANG430ErrorMessageInStatusMemo(result_code: Int64);
    var
      p_error_message: PChar;
      error_message: String;
    begin
      p_error_message := get_error_string(result_code);
    //  StrLCopy(PChar(error_message), p_error_message, StrLen(p_error_message));
     error_message:=p_error_message;
     Self.memo_etat.Lines.Add(error_message);
    end;
    Oui oui, j'avoue que j'ai fais un peu n'importe quoi sur la fin car il commencait à m'énerver

    Citation Envoyé par Paul TOTH Voir le message
    attention aussi à la convention d'appel, cdecl ou stdcall...là ça dépend de la DLL.
    Ah bon sang ! C'était ca ! J'avais complètement zappé cette histoire étant donné que j'ai repris une unité d'un projet que j'avais fais il y a 2 ans. Bon je te fais pas la bise mais sache que le coeur y est

    @+

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 553
    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 553
    Points : 25 133
    Points
    25 133
    Par défaut
    J'ai récemment fait aussi un GetLastError, GetLastMessage mais j'ajoute une fonction GetLastMessageSize pour savoir combien de mémoire dois-je alloué pour le récupérer ... une petite tricherie bien pratique ...

    Attention, si tu retournes un pointeur, c'est la DLL qui doit le libérer, et non l'application appelante, ... j'ai aussi fait ce principe pour des objets internes avec une TList et une fonction genre CloseHandle

    je préfère une procédure avec un pointeur pré-alloué qu'une fonction

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    {* -----------------------------------------------------------------------------
    GetLastErrorMessageSize renvoie la taille du Message d'erreur actuellement disponible
    @return taille du dernier message d'erreur sans le zéro terminal
    ------------------------------------------------------------------------------ }
    function GetLastErrorMessageSize: Integer; stdcall;
    begin
      if HaveInternalError() then
      begin
        Result := Length(GetInternalError());
      end
      else
      begin
        try
          Result := Length(T***Manager.GetModule().LastErrorMessage);
        except
          on E: Exception do
          begin
            SetInternalError(E.Message);
            Result := Length(GetInternalError());
          end;
        end;
      end;
    end;
     
    {* -----------------------------------------------------------------------------
    GetLastErrorMessage renvoie le Message d'erreur actuellement disponible
    @param Msg buffer qui recevra le texte du message
    @param MsgLen taille maximal du buffer comprenant le zéro terminal
    ------------------------------------------------------------------------------ }
    procedure GetLastErrorMessage(Msg: PChar; MsgLen: Integer); stdcall;
    var
      MaxLen: Integer;
    begin
      if HaveInternalError() then
      begin
        ZeroMemory(Msg, MsgLen);
        MaxLen := Length(GetInternalError()) + 1;
        if MsgLen > MaxLen then
           MsgLen := MaxLen;
        CopyMemory(Msg, @GetInternalError()[1], MsgLen - 1);
      end
      else
      begin
        try
          ZeroMemory(Msg, MsgLen);
          MaxLen := GetLastErrorMessageSize() + 1;
          if MsgLen > MaxLen then
            MsgLen := MaxLen;
          CopyMemory(Msg, @TModuleImportPHPManager.GetModule().LastErrorMessage[1], MsgLen - 1);
        except
          on E: Exception do
          begin
            SetInternalError(E.Message);
          end;
        end;
      end;
    end;
    bon, je triche avec la string pour allouer un pointeur ...

    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
    {* -----------------------------------------------------------------------------
    GetLastErrorMessage récupère les derniers messages d'Erreurs
    @return Message d'Erreur
    ------------------------------------------------------------------------------ }
    function T***Wrapper.GetLastErrorMessage: string;
    var
      _GetLastErrorMessageSize: function(): Integer; stdcall;
      _GetLastErrorMessage: procedure(Msg: PChar; MsgLen: Integer); stdcall;
      MessageSize: Integer;
    begin
      @_GetLastErrorMessageSize := GetProcAddress('GetLastErrorMessageSize');
      @_GetLastErrorMessage := GetProcAddress('GetLastErrorMessage');
     
      MessageSize := _GetLastErrorMessageSize();
      if MessageSize > 1 then
      begin
        SetLength(Result, MessageSize);
        _GetLastErrorMessage(@Result[1], MessageSize + 1); // une string contient toujours le zéro terminal
      end
      else
        Result := '';
    end;
    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

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

Discussions similaires

  1. Récupération de cellules xls dans une chaine de caractére
    Par maissaab dans le forum Général Python
    Réponses: 0
    Dernier message: 12/03/2012, 10h10
  2. Réponses: 1
    Dernier message: 11/02/2009, 17h50
  3. Variable utilisée dans une chaine de caractères
    Par cchampion2fr dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 07/10/2008, 13h46
  4. Réponses: 10
    Dernier message: 17/11/2006, 15h20
  5. problème d'insértion et de suppression dans une chaine de caractère.
    Par othmane126 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 19/08/2006, 19h54

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