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 :

[D6] Lire sous D6 le type (char **) d'une DLL en C++


Sujet :

Langage Delphi

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Points : 330
    Points
    330
    Par défaut [D6] Lire sous D6 le type (char **) d'une DLL en C++
    Bonjour,
    Presque tout est dit dans le titre : j'utilise depuis un programme sous D6 les fonctions d'une DLL.
    Je ne rencontre aucun problème avec le type char * (pointeur vers char) qui supporte sans problème le passage au type pchar puis string.

    Par contre, je suis coincé pour une fonction de cette DLL qui renvoit un "pointer to a NULL-terminated array of feature string pointers", soit en C++ le type char **
    Je n'arrive pas à trouver l'équivalent sous Delphi (j'ai essayé array of pchar sans succès).

    Est ce que quelqu'un aurait déjà été confronté à cette problématique ?

    Merci d'avance pour vos réponses...

  2. #2
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Ca signifie que la fonction va te renvoyer un tableau de PChar.

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    type
      TbPChar = array[0..$FFFF] of PChar;
     
    procedure MaFonction(var Tb : TbPChar);
    Le fait de définir le paramètre avec le spécificateur var en fait automatiquement un pointeur. Donc il suffit d'indiquer dans le type, sur quoi tu pointes.

    Remarque, tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    procedure MaFonction(var Tb : PChar);
    Tu pourras ainsi lire directement le premier élément du tableau. Puis pour lire le suivant :
    Tu as le prototype C complet ?

    Il se peut aussi (voir même probable) que la fonction attende que tu lui fournisse un pointeur sur un tableau de PChar, qu'elle remplira avec les références sur les chaînes à renvoyer. Tout dépend des spécifications...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Points : 330
    Points
    330
    Par défaut
    Merci pour ta réponse rapide.

    Le proto en C++ est le suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MON_API char ** getlist()
    {
      char    **ma_list = NULL;
      ma_list = mamethodeDLL(mes parametres);
     
      return ma_list;
    }
    Evidement, mamethodeDLL renvoit le type (char **)
    J'avais appliqué peu ou prou tes conseils mais avec un tableau dynamique, le nombre d'éléments de la liste n'étant pas connu à l'avance.
    Je sèche plutôt sur l'exploitation du tableau, le high(apchar) renvoyant -1...
    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
     
    TArrayPChar = array of pchar;
    ...
    function TILicensingManager.TestMaMethod(): TArrayString;
    var
      apchar: TarrayPChar;
      apstring: TArrayString;
      iIndex: integer;
    begin
      try
        apchar := GetList;
        SetLength(apstring,high(apchar));
        for iIndex := 0 to high(apchar) do
          apstring[iIndex] := pChar(apchar[iIndex]);
        Result := apstring;
    ...

  4. #4
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Tu ne pourras pas deviner tout seul la longueur du tableau.
    Ton API doit prévoir un moyen de connaitre la longueur du tableau (taille fixe, Terminé par un pointeur NULL, appel à une autre fonction de l'API...).

    Je ne te conseillerais pas d'utiliser un tableau dynamique, mais plutôt un simple pointeur que tu castes ensuite violemment en tableau.
    Avec un tableau dynamique, j'aurais tendance à penser que le compilateur va essayer de le finaliser à la fin. Ce qui risque de donner des résultats inatendus.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Points : 330
    Points
    330
    Par défaut
    Oui, l'API met un pointeur NULL à la fin du tableau.

    En fait, je crois qu'il va me falloir prendre quelques cours & FAQ élémentaires sur la gestion des pointeurs...

    J'ai fait ça dans ma jeunesse mais il n'en est pas resté grand chose.

    Je retiens aussi ta suggestion de pointeur casté en tableau.

    Merci de ton aide, je mets la solution dès que ça marche

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Points : 330
    Points
    330
    Par défaut
    Me revoilà...
    La solution comme promis :
    Le passage par une liste chainée !

    Côté C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct MaStructure
    {
      MaStructure* next;
      char* param1;
      int param2;
    };
    La méthode renvoit un pointeur vers cette structure qui est alimentée en boucle

    Côté Delphi, les types
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      TMaStructure = record
        next: Pointer;
        param1: pchar;
        param2: integer;
      end;
     
      PStructure = ^TMaStructure;
    Puis le code d'exploitation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      apStructure: PStructure ;
      aStructure: TMaStructure ;
    ...
    apStructure := <Appel à ma fonction de DLL>;
    while apStructure<> nil do
        begin
          aStructure:= apStructure^;
          //Exploitation de apStructure.param1 et param2
          apStructure:= aStructure.next;
        end;
    Merci Frank pour ton aide !

  7. #7
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    De rien .

    En fait, tu t'en es sorti tout seul. La solution que je te proposais était plutôt (avec la fonction qui renvoie un tableau de PChar, terminé par un PChar à NIL) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var 
      result : PChar;
     
    begin
      result := <Appel à ma fonction de DLL>;
      while result<>nil do
      begin
        ShowMessage(StrPas(result));     // exploitation de result^
     
        // Passage à l'élément suivant
        inc(result, 4);   
       end;

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

Discussions similaires

  1. Lire un champ oracle type long avec une requête ODBC
    Par guidav dans le forum Général VBA
    Réponses: 1
    Dernier message: 02/07/2011, 17h27
  2. Je suis perdu avec le type *wstring d'une DLL C++
    Par alain8550 dans le forum C++/CLI
    Réponses: 1
    Dernier message: 14/04/2010, 21h48
  3. [WD12] récupération d'un Char* d'une dll
    Par CTotophe85 dans le forum WinDev
    Réponses: 11
    Dernier message: 08/10/2008, 09h27
  4. Array subscript has type 'char'
    Par obelix dans le forum C
    Réponses: 11
    Dernier message: 31/10/2005, 18h21
  5. Réponses: 2
    Dernier message: 26/04/2004, 13h55

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