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

C# Discussion :

Interop : Import Structure complexe C vers C#


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut Interop : Import Structure complexe C vers C#
    Bonjour,

    Je viens à vous car, malgré lecture de la FAQ sur les interop, je n'arrive pas à utiliser mes structures C dans mon programmes C#.

    Voici le code C des structures :
    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
    typedef enum
    {
    	...
    } PlayerStatus;
     
    typedef enum
    {
    	...
    } STPlayerCommandType;
     
    #pragma pack(1)
    typedef struct
    {
        PlayerStatus                       Status;                             // The status of the command execution
        char                               Message[2048];   				   // The message displayed into the console (including color tags)
        union
        {
            struct                                                               // The extended info field (subject to evolution)
            {
                // Common use fields
                unsigned long                DataByteBufferLength;               // The length of the content of following buffers
                unsigned char                DataByteBufferValue        [512];   // The buffer containing byte values of data issued from the command execution
                unsigned char                DataByteBufferMask         [512];   // The buffer containing byte mask of data issued from the command execution
                unsigned long                DataByteBufferDifferenceCount;      // The number of differences in the buffer for comparison commands
                unsigned long                Value;                              // The standard single numeric value issued from the command execution
     
                // Specialized fields :
     
                // Reader's commands related fields
                unsigned long                RdRrc;                              // The reader return code
                unsigned long                RdSw1;                              // The transaction's status word byte 1
                unsigned long                RdSw2;                              // The transaction's status word byte 2
     
                // Emulator's commands related fields
                unsigned long                EmuCpuRegPc;                        // The emulator's CPU register PC
                unsigned long                EmuCpuRegSp;                        // The emulator's CPU register SP
                unsigned long                EmuCpuRegAccu;                      // The emulator's CPU register ACCU
                unsigned long                EmuCpuRegX;                         // The emulator's CPU register X
                unsigned long                EmuCpuRegY;                         // The emulator's CPU register Y
                unsigned long                EmuCpuRegCsr;                       // The emulator's CPU register CSR
                unsigned long                EmuCpuRegDsr;                       // The emulator's CPU register DSR
                unsigned long                EmuCpuRegCc;                        // The emulator's CPU register CC
     
                // Player helper fields
                PlayerCommandType          CommandType;                        // The type of the command as parsed by STPlayer
            } Info;
            char                             Reserved[2048];                     // For internal use only
        };
    } PlayerAnswer, *PPlayerAnswer;
    #pragma pack()
    Donc, pour créer le même type de structure en C#, je commence par créer mes énumérateurs, facilement.
    Ensuite, je crée ma structure englobant l'autre ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // PlayerAnswer structure
            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public class PlayerAnswer
            {
                public PlayerStatus Status;                             // The status of the command execution
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
                public char[] Message;   // The message displayed into the console (including color tags)
     
                public Info Info;
     
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2048)]
                public char[] Reserved;
            }
    Puis la structure "Info" :
    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
    // Info Structure
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public class Info
            {
                // Common use fields
                public ulong DataByteBufferLength;               // The length of the content of following buffers
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
                public char[] DataByteBufferValue;   // The buffer containing byte values of data issued from the command execution
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
                public char[] DataByteBufferMask;   // The buffer containing byte mask of data issued from the command execution
                public ulong DataByteBufferDifferenceCount;      // The number of differences in the buffer for comparison commands
                public ulong Value;                              // The standard single numeric value issued from the command execution
     
                // Specialized fields :
     
                // Reader's commands related fields
                public ulong RdRrc;                              // The reader return code
                public ulong RdSw1;                              // The transaction's status word byte 1
                public ulong RdSw2;                              // The transaction's status word byte 2
     
                // Emulator's commands related fields
                public ulong EmuCpuRegPc;                        // The emulator's CPU register PC
                public ulong EmuCpuRegSp;                        // The emulator's CPU register SP
                public ulong EmuCpuRegAccu;                      // The emulator's CPU register ACCU
                public ulong EmuCpuRegX;                         // The emulator's CPU register X
                public ulong EmuCpuRegY;                         // The emulator's CPU register Y
                public ulong EmuCpuRegCsr;                       // The emulator's CPU register CSR
                public ulong EmuCpuRegDsr;                       // The emulator's CPU register DSR
                public ulong EmuCpuRegCc;                        // The emulator's CPU register CC
     
                // Player helper fields
                public PlayerCommandType CommandType;                        // The type of the command as parsed by Player
            }
    Cette structure est utilisé par le biais de la méthode suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            PlayerAnswer answer;
     
            public int SendCommand()
            {
                commandState = P_Command(out answer, "AA_I2C_READ 02");
    			return commandState;
            }
    Aucune erreur apparente, or les valeurs que je devrais obtenir dans ma structure Info ne sont pas celles souhaitées.
    Ainsi, lorsque j'exécute cette commande, les variables de la structure Info devrait contenir ceci :
    - CommandType = PlayerCommandType_Undetermined -> OK
    - DataByteBufferDifferenceCount = 0 -> OK
    - DataByteBufferLength = 0x0000000000000002
    - DataByteBufferMask = 0xFF... -> OK
    - DataByteBufferValue = 0xa0

    Or,
    - DataByteBufferLength = 0x000000a000000002
    - DataByteBufferValue = ""

    Savez-vous d'où viendrait le problème ? Peut-être un problème d'alignement ?

    Cordialement,
    Tehko

  2. #2
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Bonjour,

    J'ai joué un peu avec les composants COM+ pour faire de l'Interop entre du VB6 et du C#, mais je n'ai pas été si loin dans la complexité des types des variables entre les 2 langages.

    Néanmoins je pencherais effectivement peut être pour un problème d'alignement ou un soucis du genre, car je sais que la taille des types en .net n'est plus la même que dans les autres langages (mais je n'ai pas les valeurs précises en mémoire)

    As tu par hasard essayé de passer les valeurs mais sans passer par la structure (de simple variable long, ulong etc) juste pour savoir si le problème se produirait également ?

  3. #3
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    Je ne suis pas sûr d'avoir bien compris ta question. Tu veux dire qu'il faudrait que je supprime les structures de façon à récupérer uniquement leurs paramètres ?

    Si c'est çà, je ne crois pas que cela soit possible car en fait j'ai récupéré une DLL qui contient ces structures. Leur description est faite dans un fichier d'en-tête (.h) que j'ai présenté au début de la discussion.
    Je ne dispose que de ce fichier de description que je ne dois en aucun cas modifier donc la seule possibilité qui s'offre à moi est d'essayer de reproduire cette description en C#.

  4. #4
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Oui je comprends ton soucis. L'idée ici était de seulement faire un test avec des données d'un type un peu moins complexe qu'une structure (je pensais par exemple à essayer avec un ulong). Pour pouvoir mettre en avant un possible problème lié à l'utilisation de structure.

    Mais je n'ai pas dis qu'il faillait laisser la chose en l'état dans ton programme final ;-)

  5. #5
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    bonjour Tehko

    Referes toi toujours au guide c# MSDN doc pour les types....
    Rubrique :Platform Invoke Data Types
    long (unmanged C) => .Net : System.Int32 (signe .4 octets ..32 bits)
    unsigned long (unmanged C) =>.Net :System.UInt32 (non-signe 4 octets ..32 bits)
    Maintenant que veut dire un long en C# ceci:
    Rubrique : long (C# Reference)
    The long keyword denotes an integral type that stores values according to the size and range shown in the following table.

    long Signed 64-bit integer System.Int64 (8 octets)
    ulong Unsigned 64-bit integer System.UInt64 (8 octets)
    Ce ulong de c# (8 octets) n'a rien à voir avec le type ulong de C (4 octets)...
    D' ailleurs l'equivalent en C du ulong c# est un double ...helas(voir la rubrique cite en premier)......

    bon code...

  6. #6
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    Merci MABROUKI, ayant le même genre de projet même si un moins complexe je n'avais pas trouvé cette documentation très intéressante.

    Mais tu vas dans le sens de mon idée sur un problème de taille en octets pour les types de variables

  7. #7
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Avril 2010
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2010
    Messages : 34
    Points : 20
    Points
    20
    Par défaut
    Super !

    Merci Mabrouki. Tout est rentré en ordre en remplaçant ulong par UInt32.

    Merci infosam76 pour ton aide.

  8. #8
    Membre expert


    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2006
    Messages
    970
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 970
    Points : 3 304
    Points
    3 304
    Par défaut
    De rien je suis également content d'avoir la solution figure toi ;-)

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

Discussions similaires

  1. Libxml2 - Structures complexe vers DOM
    Par ryan.tkd13 dans le forum Bibliothèque standard
    Réponses: 0
    Dernier message: 14/01/2014, 13h31
  2. Import XML structure complexe
    Par kenobyalex dans le forum VBA Access
    Réponses: 9
    Dernier message: 08/04/2008, 17h37
  3. Importation de fichier CSV vers une base Interbase
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 15/03/2005, 15h18
  4. passer structure de C# vers C++
    Par belayay dans le forum MFC
    Réponses: 3
    Dernier message: 23/02/2005, 17h01
  5. [langage] structures complexes et affichage
    Par mat21 dans le forum Langage
    Réponses: 5
    Dernier message: 18/02/2004, 15h38

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