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

Delphi Discussion :

traduction structure en Delphi (suite)


Sujet :

Delphi

  1. #1
    Membre émérite
    Avatar de skywaukers
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2005
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 216
    Points : 2 306
    Points
    2 306
    Par défaut traduction structure en Delphi (suite)
    bonsoir,

    désolé de vous embêter à nouveau avec du pascal basique, mais voilà : j'ai essayé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    KN_OBJ = record
                  ObjType   : Integer; // object type
                  AddrHigh  : Integer; // object address - high byte
                  AddrLow   : Integer; // object address - low byte
                  Index     : Integer; // index address for object arrays
                  Val : record
                         case Integer of
                          0 : (I : LongInt); // object value - integer
                          1 : (D : Double);  // object value - double/single
                        end;
                  Exponent  : Integer; // object value - exponent
                  BitNumber : Integer;// specific bit number
                 end;
    une variable de ce type est envoyée à une dll. Si je renseigne val.I, cela fonctionne, mais elle ne veut rien prendre si je renseigne val.D

    pourtant la dll fonctionne correctement avec un pgm VB

    merci,
    Dany

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Foa,

    Ben oui, tu voulais une structure en Delphi qui corresponde à une union pour les champs I et D (pour toi Val.I et Val.D).

    C'est le cas, et ces 2 champs utilisent la même zone mémoire.

    Sinon, je ne vois pas ce que tu veux dire.

    ps : pourquoi un nouveau sujet, tu pouvais continuer dans l'autre.

  3. #3
    Membre émérite
    Avatar de skywaukers
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2005
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 216
    Points : 2 306
    Points
    2 306
    Par défaut
    bonsoir et merci,

    j'ai fait un nouveau sujet car j'avai mis le précédent résolu, pensant que effectivement cela était la solution, bien que j'avais déjà éssayé la solution de Paul Toth à vrai dire.
    En fait mon problème est le suivant :
    je cherche à dialoguer avec une dll de control technic qui permet d'écrire des paramètres dans un variateur électronique. Cette dll exporte pleins de functions, dont une fonction readobject et une fonction writeobject qui prennent en paramètre entre autre un pointeur vers une variable de ce fameux type. Hors c ok pour les paramètres entier, mais il refuse de prendre les valeurs décimales. La raison est surement ailleurs, mais je voulait au moins éliminer cette piste, ce qui semble être le cas.

    Encore merci,
    Dany

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    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 586
    Points : 25 262
    Points
    25 262
    Par défaut
    en général mes cases structure sont à la fin, mais ceci SANS val fonctionne peut-être mieux ? En deplhi, l'union n'est pas nommé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
        KN_OBJ = record
            ObjType   : Integer; // object type
            AddrHigh  : Integer; // object address - high byte
            AddrLow   : Integer; // object address - low byte
            Index     : Integer; // index address for object arrays
            case Integer of
                0 : (I : LongInt); // object value - integer
                1 : (D : Double);  // object value - double/single
            end;
            Exponent  : Integer; // object value - exponent
            BitNumber : Integer;// specific bit number
       end;
    un exemple flagrant, la Structure _LDT_ENTRY contient l'union Bytes et Bits
    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
     
    typedef struct _LDT_ENTRY { // ldte  
        WORD LimitLow;  
        WORD BaseLow; 
        union { 
            struct { 
                BYTE BaseMid; 
                BYTE Flags1; 
                BYTE Flags2; 
                BYTE BaseHi; 
            } Bytes; 
            struct { 
                DWORD BaseMid : 8; 
                DWORD Type : 5; 
                DWORD Dpl : 2; 
                DWORD Pres : 1; 
                DWORD LimitHi : 4; 
                DWORD Sys : 1; 
                DWORD Reserved_0 : 1; 
     
                DWORD Default_Big : 1; 
                DWORD Granularity : 1; 
                DWORD BaseHi : 8; 
            } Bits; 
        } HighWord; 
    } LDT_ENTRY, *PLDT_ENTRY;
    en Delphi, ce n'est pas nommé (bon en plus nous n'avons pas la possibilité de manipulé de bit comme des Entiers, car cela cache un mask et un shr)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      _LDT_ENTRY = record
        LimitLow: Word;
        BaseLow: Word;
        case Integer of
          0: (
            BaseMid: Byte;
            Flags1: Byte;
            Flags2: Byte;
            BaseHi: Byte);
          1: (
            Flags: Longint);
      end;

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Die,
    Citation Envoyé par ShaiLeTroll
    en général mes cases structure sont à la fin, mais ceci SANS val fonctionne peut-être mieux ? En deplhi, l'union n'est pas nommé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
        KN_OBJ = record
            ObjType   : Integer; // object type
            AddrHigh  : Integer; // object address - high byte
            AddrLow   : Integer; // object address - low byte
            Index     : Integer; // index address for object arrays
            case Integer of
                0 : (I : LongInt); // object value - integer
                1 : (D : Double);  // object value - double/single
            end;
            Exponent  : Integer; // object value - exponent
            BitNumber : Integer;// specific bit number
       end;
    Non, les champs variants ainsi déclarés doivent être les derniers dans le record, et deplus les case of ne doit pas être fermé par un end.

    il faudrait donc faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type
        KN_OBJ = record
            ObjType   : Integer; // object type
            AddrHigh  : Integer; // object address - high byte
            AddrLow   : Integer; // object address - low byte
            Index     : Integer; // index address for object arrays
            Exponent  : Integer; // object value - exponent
            BitNumber : Integer;// specific bit number
            case Integer of
                0 : (I : LongInt); // object value - integer
                1 : (D : Double);  // object value - double/single
       end;
    Mais ça risque de poser des problèmes à skywaukers, la structure étant apparemment imposée par sa dll ?


    pour skywaukers : es-tu sûr que ta dll travaille avec un double ?

    Ton problème semble indiquer une erreur dans la taille des champs déclarés.

    Il faut donc que tu vérifies leur taille effective pour la dll, et que tu déclares les types en fonction de cela.

  6. #6
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    La structure utilisée pour le case a déjà été discutée et approuvée dans l'autre thread. Ce que donne skywaukers est correct.

    Par contre, comme l'a fait remarquer droggo, il est fort possible que la DLL ne travaille pas avec un Double, mais bien avec un Single, qui a la même taille que le Integer.

    Je donnerais donc ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    KN_OBJ = record
      ObjType   : Integer; // object type
      AddrHigh  : Integer; // object address - high byte
      AddrLow   : Integer; // object address - low byte
      Index     : Integer; // index address for object arrays
      Val : record
        case Integer of
          0 : (I : LongInt); // object value - integer
          1 : (S : Single);  // object value - single
      end;
      Exponent  : Integer; // object value - exponent
      BitNumber : Integer; // specific bit number
    end;

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    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 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Citation Envoyé par droggo
    Non, les champs variants ainsi déclarés doivent être les derniers dans le record, et deplus les case of ne doit pas être fermé par un end.
    Je n'étais pas sure, effectivement, tous mes records variables sont à la fin ... sinon ceci est possible ...

    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
    type
        KN_OBJ = record
            ObjType   : Integer; // object type
            AddrHigh  : Integer; // object address - high byte
            AddrLow   : Integer; // object address - low byte
            Index     : Integer; // index address for object arrays
            case Integer of
                0 : (
                     I : LongInt;// object value - integer
                     );             
                1 : (
                     D : Double;  // object value - double/single
                     Exponent  : Integer; // object value - exponent
                     BitNumber : Integer; // specific bit number
                    );
       end;
    Après si il y a avait une confusion de Double / Single, n'y aurait-il pas un problème avec le champ Exponent (j'ignore comment le C++ aligne un champ variable de longueur différent Integer et Double (4 et 8)) mais cela doit être assez standard, ...
    Attention, il faut bien initialisé sa structure car dans une variable locale, la structure contient ce qui se trouvait à la mémoire, un ZeroMemory peut-être prudent à faire ... si c'est par pointer, via New, normalement la mémoire est "nullifiée"

  8. #8
    Membre émérite
    Avatar de skywaukers
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2005
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 216
    Points : 2 306
    Points
    2 306
    Par défaut
    bonjour,

    oui la structure est imposée, et j'ai copiée la version c du fichier d'aide de celle ci.
    Je vais quand même essayer avec single.
    la structure est en variable locale, mais je l'initialise systématiquement. Cela fait un moment que je tourne en rond sur ce pb et en plus c difficile de me faire aider car il faut le variateur pour voir le résultat car bien sûr il n'y a pas d'erreur retournée par a dll

    Merci encore, je vous tiens au courant dès que j'ai essayé.
    Dany

  9. #9
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Gae,
    Citation Envoyé par skywaukers
    bonjour,

    oui la structure est imposée, et j'ai copiée la version c du fichier d'aide de celle ci.
    Je vais quand même essayer avec single.
    la structure est en variable locale, mais je l'initialise systématiquement. Cela fait un moment que je tourne en rond sur ce pb et en plus c difficile de me faire aider car il faut le variateur pour voir le résultat car bien sûr il n'y a pas d'erreur retournée par a dll

    Merci encore, je vous tiens au courant dès que j'ai essayé.
    Dany
    Tu dois bien avoir une doc pour cette DLL, donc pour la structure en question.

  10. #10
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Bonjour,

    j'ai testé la compatibilité struct/record et elle semble bonne.

    Code c : 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
    58
    59
    60
    61
    62
    // .h ////////////////////////////////
    #ifndef _DLL_H_
    #define _DLL_H_
     
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
     
    typedef struct {
      int ObjType;			// object type
      int AddrHigh;			// object address - high byte
      int AddrLow;			// object address - low byte
      int Index;			// index address for object arrays
      union {
        long int I;			// object value - integer
        double D;			// object value - double/single
      } Val;
      int Exponent;			// object value - exponent
      int BitNumber;		// specific bit number
    } KN_OBJ;
     
    DLLIMPORT void FonctionAffiche ( KN_OBJ * Test );
     
    #endif /* _DLL_H_ */
    // .c ////////////////////////////////
    #include "dll.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    DLLIMPORT void FonctionAffiche ( KN_OBJ * Test )
    {
       printf(" %i %i %i %i %Id %lf %i %i \n" , Test->ObjType , Test->AddrHigh , Test->AddrLow  ,
                                         Test->Index , Test->Val.I , Test->Val.D , Test->Exponent , 
                                         Test->BitNumber );   
    }
     
     
    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                           DWORD reason        /* Reason this function is being called. */ ,
                           LPVOID reserved     /* Not used. */ )
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
            break;
     
          case DLL_PROCESS_DETACH:
            break;
     
          case DLL_THREAD_ATTACH:
            break;
     
          case DLL_THREAD_DETACH:
            break;
        }
     
        /* Returns TRUE on success, FALSE on failure */
        return TRUE;
    }
    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
    program Project1;
    {$APPTYPE CONSOLE}
    uses
      SysUtils;
    type
     
      TKN_OBJ = packed record  // les packed ne servent à rien ici ^^
       ObjType  : Integer;
       AddrHigh : Integer;
       AddrLow  : Integer;
       Index    : Integer;
       Val : packed record
              case Integer of
                0 :( I : Longint );
                1 :( D : Double );
              end;
       Exponent : Integer;
       BitNumber: Integer;
      end;
     
      procedure FonctionAffiche( var Test : TKN_OBJ ); cdecl ;external 'TestDll.dll' ;
    var Test : TKN_OBJ ;
    begin
     
      Test.ObjType  := 1;
      Test.AddrHigh := 2;
      Test.AddrLow  := 3;
      Test.Index    := 4;
      Test.Val.I    := 10;
      Test.Exponent  := 5;
      Test.BitNumber := 6;
     
      FonctionAffiche(Test);
     
      Test.Val.D := 1.2345;
     
      FonctionAffiche(Test);
     
      Readln;
    end.
    Sortie
    1 2 3 4 10 0.000000 5 6
    1 2 3 4 309237645 1.234500 5 6

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Fia,

    Ce que le programme te sort par rapport à ce que tu lui mets directement n'est pas représentatif de ce que ta DLL va mettre dans la structure : les données mises et affichées sont évidemment cohérentes, utilisant la même définition du record.

    Il faut voir ce que te met effectivement ta DLL.

    Il faut également se méfier de l'alignement des champs dans la structure, qui peut varier d'une implémentation à l'autre dans un même langage, et donc encore plus aisément d'un langage à l'autre.

Discussions similaires

  1. Commande Delphi - suite
    Par ghan77 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 17/01/2006, 11h24
  2. [C#] Convertion de structure vers Delphi .NET
    Par Laurent Dardenne dans le forum Windows Forms
    Réponses: 21
    Dernier message: 08/01/2005, 02h36
  3. Traduction C++ vers Delphi
    Par lil_jam63 dans le forum Langage
    Réponses: 6
    Dernier message: 05/07/2004, 13h10
  4. [langage] [traduction] Structure SWITCH
    Par rbh dans le forum Langage
    Réponses: 6
    Dernier message: 07/06/2004, 17h24
  5. probleme traduction C vers Delphi
    Par zinaif dans le forum Langage
    Réponses: 3
    Dernier message: 27/06/2003, 08h51

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