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 :

Passage de parametre shortString à une Dll écrite en C


Sujet :

Langage Delphi

  1. #1
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Passage de parametre shortString à une Dll écrite en C
    Bonjour,

    Je commence à m'arracher les cheveux pour récupérer une info d'un autre soft via une DLL. Voici mon problème:

    Ceci marche dans un programme Visual Basic 6, pour récupérer la variable DSetting.FileName:

    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
    Type Datsetting
        SaveData As Long
        Autoinc As Long
        Fmt As Long
        Mpafmt As Long
        Sephead As Long
        Smpts As Long
        Caluse As Long
        Filename As String * 256
        Specfile As String * 256
        Command As String * 256
    End Type
    
    Dim Dsetting As Datsetting
    
    Declare Function GetDatSetting Lib "DMPA3.DLL" Alias "#41" (Dsetting As Datsetting) As Long
    
    Call GetDatSetting(Dsetting)
    Voici ce que je fais avec Delphi 2005:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type 
      DatSetting = record  
      SaveData, AutoInc,Fmt,MpaFmt,Sephead, Smpts , CalUse:integer;
      FileName,SpecFile,Command: ShortString;end;
    
    var
      DSetting:DatSetting;
    
    implementation
    
    {$R *.dfm}
    
    function GetDatSetting(var DSetting:DatSetting) :integer; stdcall;external 'DMPA3.dll';
    Mon problème se situe dans DSetting.FileName:
    Il me manque le premier caractère de la chaine, et j'ai plein de #0 dans ma variable récupérée.

    Solution bricolée:
    Remplacer la déclaration du type DatSetting par ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type DatSetting = record
      SaveData, AutoInc,Fmt,MpaFmt,Sephead, Smpts , CalUse:integer;
      FileName, SpecFile,Command:array[0..255] of char;end;
    et dans ce cas, je peux récupérer ma chaine de texte dans le tableau...

    Je cherche donc quelqu'un qui pourrait m'aider à récupérer ma chaine proprement...

    d'avance un grand merci

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    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 665
    Points : 25 459
    Points
    25 459
    Par défaut
    Ben c'est propre
    Cela n'a rien de choquant, c'est un type String de 255, comme c'est du VB, c'est un tableau et la fin est indiqué par un zéro terminal

    alors que le type ShortString de Delphi, déjà il commence à 1, et le premier octet indique la longueur de la chaine !

  3. #3
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    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
    {$X+}
     
    type 
      TDatSetting = packed record  
        SaveData, 
        AutoInc,
        Fmt,
        MpaFmt,
        Sephead, 
        Smpts, 
        CalUse : LongInt;
        FileName,
        SpecFile,
        Command: array[0..255] of AnsiChar; // interprété comme AnsiString
      end;
     
    function GetDatSetting(var aDSetting: TDatSetting): integer; stdcall;
     
    var
      DatSetting : TDatSetting;
     
    implémentation
     
    const
      Lib = 'DMPA3.dll';
     
    function GetDatSetting; external Lib name 'GetDatSetting';
     
    end.

  4. #4
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Ok, je vais me débrouiller avec un array[0..255] of AnsiChar...

    Le code proposé par Dr. Who donne le même résultat, mais je ne comprends pas trop la double déclaration de la fonction GetDatSetting... Je vais donc continuer comme j'avais proposé dans mon premier post.

    J'ai bien compris que mon problème était dû à une différence de codage du premier octet d'un language à l'autre, je vais donc utiliser quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (datSetting.FileName[i]<>#0) do begin
      FileName:=FileName + string(DatSetting.FileName[i]);
      inc(i);
    end;
    pour repasser ensuite en string...

    __

    Bonne prog à tous et toutes,

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 812
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 812
    Points : 13 527
    Points
    13 527
    Par défaut
    L'affectation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FileName := DatSetting.FileName;
    fonctionne sans boucle. En dernière extrémité, tu peux aussi utiliser StrPas().

  6. #6
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    En effet, ça marche très bien, merci. Et ça simplifie pas mal mon problème.
    J'y vois maintenant bien plus clair dans le passage de paramètre caractère/string.
    En fait, maintenant, ça marche.

    Merci à tous,

    A la prochaine,

    Aurélien

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    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 665
    Points : 25 459
    Points
    25 459
    Par défaut
    Sinon 0..255, cela fait 256 caractères ! Attention à cela !

  8. #8
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    oui, et ??

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    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 665
    Points : 25 459
    Points
    25 459
    Par défaut
    la ShortString, c'était 1 à 255 donc 255 de longueur (avec 0 comme indicateur de longueur justement), d'où l'erreur initial !

    avais tu noté aussi l'ajout du mot clé packed ?
    dans ton cas, comme il n'y a que des Long et des chaines de 256 caractères, cela n'influence pas ! mais avec des types de longueur 1 ou 2, cela aurait aligné les membres de la structure, si tu as d'autres DLL à mapper, il faut le savoir !

  10. #10
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    oui, j'avais bien vu le packed. Si j'ai bien compris, il sert lors de l'allocation de la mémoire par windows à utiliser un espace mémoire continu, et donc de pouvoir écrire et/ou lire d'un coup dans plusieurs cases se suivant... juste?

    Je suis encore confronté à un petit problème pour écrire dans le tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DSetting.FileName:='c:\brol\machin123.mpa'
    marche, alors que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
    Name:string;
    begin
    Name:='c:\brol\machin123.mpa';
    DSetting.FileName:=Name;
    me donne le message "E2010 Incompatible types: 'Array' and 'String'

    et je peux changer Name en array[0..255] of AnsiChar, c'est pas mieux...

    Une idée?

    Merci,

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    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 665
    Points : 25 459
    Points
    25 459
    Par défaut
    utilise la fonction StrPLCopy

  12. #12
    Candidat au Club
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    En effet!

    j'étais sur la piste, mais avec un StrLCopy, et je n'arrivais pas à le faire marcher.

    Maintenant, j'ai

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StrPLCopy(DSetting.FileName,Edit9.text,255);
    et ça marche très bien.

    Un grand merci,

    A la prochaine,

  13. #13
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    oui dans delphi 2009 les String et Array[...] of char fonctionne de façon transparente (c'est le compilo qui se debrouille tout seul).

    tu peux également déclarer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type 
      TDatSetting = packed record  
        SaveData, 
        AutoInc,
        Fmt,
        MpaFmt,
        Sephead, 
        Smpts, 
        CalUse : LongInt;
     
        FileName,
        SpecFile,
        Command: string[256];
      end;
    cela doit fonctionner parfaitement sans le probleme d'indexation.
    le mieux aurait été de passer par des PChar ... mais bon.


    pour la double déclaration de GetDatSetting c'est tout simple,
    la première figure dans l'interface et l'autre dans l'implementation.
    tu remarquera qu'il n'y à pas besoin de réécrire la déclaration complète de la fonction dans l'implémentation.

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 665
    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 665
    Points : 25 459
    Points
    25 459
    Par défaut
    Il me semble qu'il utilise Delphi 2005
    Sinon ils ont enfin gérés des chaines limités à plus de 255 caractères ? string[256] ! ils sont multipliés tout par deux, la taille aussi car la caractère 0 est sur deux octets ?
    cela ne pose-t-il pas un problème avec les octets au début de la chaine ?

  15. #15
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    oui les chaines sont en unicode (widestring/widechar) d'ou l'utilisation de AnsiString/AnsiChar/PAnsiChar pour ce genre de manipulation.

    c'est vrai qu'il ont un peu "chier" sur la gestion Unicode/Ansi.

    et repasser simplement en AnsiString se révèle asse fastidieux.
    ils auraient pus prévoir un truc tout simple et idiot pour passer facilement de l'un à l'autre.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 21/06/2005, 21h45
  2. [langage] Passage de paramètres dans une fonction
    Par And_the_problem_is dans le forum Langage
    Réponses: 11
    Dernier message: 28/06/2004, 08h20
  3. [langage] passage de paramètres à une fonction
    Par BARBIER dans le forum Langage
    Réponses: 4
    Dernier message: 07/05/2004, 15h46
  4. Utilisation d'une dll écrite en delphi 5 dans VB6
    Par Jean-Louis dans le forum Langage
    Réponses: 4
    Dernier message: 05/08/2002, 09h19
  5. Passage de parametre a une anim Flash 5
    Par debug dans le forum Intégration
    Réponses: 4
    Dernier message: 03/06/2002, 17h59

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