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 :

result: chaine de caractère pour une DLL


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Points : 60
    Points
    60
    Par défaut result: chaine de caractère pour une DLL
    salut

    j'ai un petit soucis au niveau d'une DLL qui contient une fonction, dont le result est une chaine de caractère. mon .exe veut apeller cette fonction (ça c'est oki), mais ce result ne doit pas être de type String ou ses compagnons, vu que je veux que cette DLL ne soit pas bridée au language Delphi, elle doit pouvoir être faite dans n'importe quel language. je dois donc utiliser les PChar je suppose, mais je n'arrive pas du tout à les faire fonctionner, alors que le type String ou ShortString est très très simple à utiliser (même code qu'une fonction "normale")

    comment je dois faire?

  2. #2
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    744
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 744
    Points : 500
    Points
    500
    Par défaut
    En effet si tu utilises des Pchar , tu devrai pas avoir de probleme !

    Es tu sûr de tes declarations des deux cotés , et de bien les passer ensuite dans des strings pour leur utilisation si cela est neccesaire !

    en fait que ce passe t'il ? ta chaine est tronqué , tu as des caracteres en trop .... ?
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    mais je n'arrive pas du tout à les faire fonctionner,
    Merci d'être plus explicite : ou est ton problème ?

    Gardes à l'esprit qu'un PChar n'est qu'un pointeur. Il doit donc toujours correspondre à un array of char (@monarray) ou à un string (PChar(monstring)) au risque d'avoir de multiples violations d'accès...
    "It's more fun to compute !"

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Points : 60
    Points
    60
    Par défaut
    j'ai des caractères en trop, et elle est tronquée quelques fois. voila le code de mon .exe (fonction apellée par la DLL):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function xGetDir(const DirID: integer): PChar; stdcall;
    begin
    Result := '';
    case DirID of
      XDIR_CONFIG    : Result := PChar(PathProg + 'Config\');
      XDIR_DLL       : Result := PChar(PathProg + 'Dll\');
      XDIR_PLUGINS   : Result := PChar(PathProg + 'PlugIns\');
      XDIR_PICTURES  : Result := PChar(PathProg + 'Images\');
      XDIR_HELP      : Result := PChar(PathProg + 'Aide\');
      XDIR_LANGUAGES : Result := PChar(PathProg + 'Languages\');
    end; // case
    end; // function
    exports xGetDir;
    ensuite, dans ce même .exe, pour tester la fonction je fais:
    ShowMessage('*' + xGetDir(XDIR_LANGUAGES) + '*');
    ça me renvoi bien ce que je veux. juste en dessous, je refais:
    ShowMessage('*' + xGetDir(XDIR_LANGUAGES) + 'PlugIns.xml');
    sauf que cette fois-ci, avant PlugIns.xml j'ai un ( qui sort de je ne sais pas trop où

    ensuite, depuis ma DLL, je fais un button qui apelle cette function du .exe, avec cette commande:
    ShowMessage('*' + xGetDir(XDIR_LANGUAGES) + '*');
    et cette fois, ça me renvoi le bon répertoire, autant de fois que je click sur le button ça fonctionne à merveille. il n'empêche que la 2eme fois que j'apelle ma fonction (que ce soit depuis le .exe ou dans la dll), il me rajoute un caractère (

    Précision: je met '*' pour bien voir si il n'y a pas d'autres caractères avant et après la chaine renvoyée

    y'a pas une histoire d'adresse mémoire qui est vidée entre temps, ou quoi que ce soit?

  5. #5
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    OK, si on réfléchis, un PChar est un pointeur sur une zone de texte. En faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Result := PChar(PathProg + 'Config\')
    ...Result contient un pointeur vers un string local à ta fonction étant la concaténation de "PathProg" et 'Config'.

    Or, quand ta fonction se termine, cette zone est libérée. Par conséquent, le pointeur ne pointe plus vers rien de valide : cette zone mémoire contient toujours sans doute ton texte, mais Windows la considère libre pour stocker d'autres choses (ce qui explique dans doute les caractères incongrus ajoutés).

    Par conséquent, ne renvoie pas de PChar. Passe plutôt un PChar en paramètre (ainsi qu'une taille de buffer, puisque tu auras certainement besoin d'utiliser StrLCopy ou une fonction de ce genre pour renvoyer ta valeur).
    "It's more fun to compute !"

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Points : 60
    Points
    60
    Par défaut
    tu aurais un petit bout de code d'exemple? parceque je veux bien passer un PChar en paramètre, le modifier dans mon .exe donc, mais j'avais déja tenté une action de ce tyle et ça n'avait pas marché

  7. #7
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Un exemple :

    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
    procedure TForm1.JeRetourneUnPchar(AResult: PChar; ABufSize: Integer);
    var
     S : string;
    begin
     S := 'Hého !';
     StrPLCopy(AResult, S, ABufSize)
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
     AResult : array [0..20] of Char;
    begin
     JeRetourneUnPchar(@AResult, Length(AResult));
     MessageDlg(String(AResult), mtWarning, [mbOK], 0);
    end;
    "It's more fun to compute !"

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Points : 60
    Points
    60
    Par défaut
    si je met ton code dans un seul .exe, ça fonctionne parfaitement. mais si je veux mettre la fonction JeRetournUnChar dans un .Exe, et l'appel dans une DLL, ça me renvoi la bonne chaine, et juste derrière un Access violation at address 72F2FF1C in module 'USP10.dll'. Read of address 00000000

    finalement, quelqu'un m'a passé ce code:
    Form du programme
    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
      TxGetDir = procedure (const DirID: integer; const pcResult: PChar;
                      var iResultSize: Cardinal); stdcall;
     
    var
      Form1: TForm1;
      xxGetDir : TxGetDir;
    implementation
     
    {$R *.dfm}
     
    function xGetDir(const DirID: integer): String;
    var pcDir : PChar;
        iDir  : Cardinal;
    begin
      xxGetDir(DirID, nil, iDir);
      pcDir := AllocMem(iDir);
      xxGetDir(DirID, pcDir, iDir);
      SetString(Result, pcDir, iDir - 1);
      FreeMem(pcDir);
    end;
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      LibModule : HMODULE;
    begin
      LibModule := LoadLibrary('TestDll.dll');
      xxGetDir := GetProcAddress(LibModule, 'xGetDir');
      Caption := xGetDir(StrToIntDef(Edit1.Text, 0));
      FreeLibrary(LibModule);
    end;
    La Dll
    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
    const
      PathProg = 'Path\';
      XDIR_CONFIG    = 0;
      XDIR_DLL       = 1;
      XDIR_PLUGINS   = 2;
      XDIR_PICTURES  = 3;
      XDIR_HELP      = 4;
      XDIR_LANGUAGES = 5;
     
    procedure xGetDir(const DirID: integer; const pcResult: PChar;
                      var iResultSize: Cardinal); stdcall;
    var
      sTmp : string;
    begin
      case DirID of
        XDIR_CONFIG    : sTmp := PathProg + 'Config\';
        XDIR_DLL       : sTmp := PathProg + 'Dll\';
        XDIR_PLUGINS   : sTmp := PathProg + 'PlugIns\';
        XDIR_PICTURES  : sTmp := PathProg + 'Images\';
        XDIR_HELP      : sTmp := PathProg + 'Aide\';
        XDIR_LANGUAGES : sTmp := PathProg + 'Languages\';
      end; // case
     
      if Assigned(pcResult) then begin
        Move(sTmp[1], pcResult^, Min(iResultSize - 1, Length(sTmp)));
      end else begin
        iResultSize := Length(sTmp) + 1;
      end;
    end;
     
    exports xGetDir;
    apparement il fonctionne à merveille, je vais donc m'en servir

    merci de votre aide rapide

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

Discussions similaires

  1. [RegEx] Décomposer une chaine de caractères pour extraire un nombre
    Par PIEPLU dans le forum Langage
    Réponses: 3
    Dernier message: 26/03/2012, 17h30
  2. Script pour remplacer une chaine de caractères par une autre
    Par babiêtiguiya dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 28/02/2012, 14h57
  3. [XL-2007] Chaine de caractère pour Email en fonction de la valeur d'une Liste
    Par brunounours dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 13/12/2011, 12h38
  4. Réponses: 3
    Dernier message: 27/04/2008, 19h10
  5. Découper une chaine de caractère pour un 'IN'
    Par Amiba dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 25/10/2007, 12h31

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