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 :

C Struct >> C# : Besoin d'aide


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 103
    Points : 97
    Points
    97
    Par défaut C Struct >> C# : Besoin d'aide
    Bonjour,

    Voici un exemple de structure en C que j'aimerai coder en C#. En fait mon idée est de faire une application capable de parser les mini-dumps de microsoft. Je travaille sur PocketPC et je génère souvent des KDMPs (mini dump) donc j'aimerai pouvoir les classer par ordre de priorité suivant le process qui crashe, ou encore la fonction appelée qui pose problème etc.

    Voici la structure qui m'intéresse (http://msdn.microsoft.com/en-us/library/ms939646.aspx):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    typedef struct _MINIDUMP_HEADER {
      ULONG32 Signature;
      ULONG32 Version;
      ULONG32 NumberOfStreams;
      RVA StreamDirectoryRva;
      ULONG32 CheckSum;
      union
      {
          ULONG32 Reserved;
          ULONG32 TimeDateStamp;
      };
      ULONG64 Flags;
    } MINIDUMP_HEADER, *PMINIDUMP_HEADER;
    Voila un début de conversion en C# mais ne connaissant pas le C, je suis très limité:
    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
     
    public struct MINIDUMP_HEADER {
      UInt32 Signature;
      UInt32 Version;
      UInt32 NumberOfStreams;
      int StreamDirectoryRva; // RVA = int (?)
      UInt32 CheckSum;
      [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
    struct Union
      {
          [System.Runtime.InteropServices.FieldOffset(0)]
          UInt32 Reserved;
          [System.Runtime.InteropServices.FieldOffset(0)]
          UInt32 TimeDateStamp;
      }
      UInt64 Flags;
    }
    Je ne sais pas vraiment que vient faire le pointeur *PMINIDUMP_HEADER et je ne connais pas vraiment ce qu'est une union par rapport à une structure ... (apparemment ce serait que Reserved et TimeDateStamp seraient inscrit à la même adresse mémoire ?? Donc en fait une seule valeur serait accessible à la fois : Reserved ou TimeDateStamp ?) .

    Si quelqu'un peut me donner un coup de main (pas de pied... ça fait trop mal ), ça serait simpa.


    Merci d'avance !
    AlnCool

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 103
    Points : 97
    Points
    97
    Par défaut
    En fait je n'ai aucune idée des offsets car la page msdn n'en dit pas plus que le bout de code C que j'ai copié dans mon premier post...
    Pour l'instant je ne peux pas vraiment tester cette structure, je n'ai pas suffisamment de vue d'ensemble du format de fichier des KDMP pour commencer à coder quelque chose...
    (en plus de ça je suis un éternel débutant donc il me faut looooooooooooooonnntemp avant de pondre un code/programme... )

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par alncool Voir le message
    Je ne sais pas vraiment que vient faire le pointeur *PMINIDUMP_HEADER
    Pas besoin de t'en préoccuper, c'est juste un raccourci syntaxique pour dire que le type PMINIDUMP_HEADER représente un pointeur vers une structure MINIDUMP_HEADER.


    Citation Envoyé par alncool Voir le message
    je ne connais pas vraiment ce qu'est une union par rapport à une structure ... (apparemment ce serait que Reserved et TimeDateStamp seraient inscrit à la même adresse mémoire ?? Donc en fait une seule valeur serait accessible à la fois : Reserved ou TimeDateStamp ?)
    C'est à peu près ça. Mais en fait tu n'as pas besoin de déclarer une nouvelle structure Union pour ça (ou si tu le fais, il faut déclarer un champ de type Union dans MINIDUMP_HEADER).

    Pour RVA, je sais pas trop ce que c'est, mais d'après la doc, il s'agit d'un pointeur, donc a priori tu peux utiliser le type IntPtr.

    En fait je pense que le mieux serait de déclarer explicitement tout le layout de la structure :

    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
    [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
    public struct MINIDUMP_HEADER {
      [System.Runtime.InteropServices.FieldOffset(0)]
      UInt32 Signature;
      [System.Runtime.InteropServices.FieldOffset(4)]
      UInt32 Version;
      [System.Runtime.InteropServices.FieldOffset(8)]
      UInt32 NumberOfStreams;
      [System.Runtime.InteropServices.FieldOffset(12)]
      IntPtr StreamDirectoryRva; // RVA = int (?)
      [System.Runtime.InteropServices.FieldOffset(16)]
      UInt32 CheckSum;
      [System.Runtime.InteropServices.FieldOffset(20)]
      UInt32 Reserved;
      [System.Runtime.InteropServices.FieldOffset(20)]
      UInt32 TimeDateStamp;
      [System.Runtime.InteropServices.FieldOffset(24)]
      UInt64 Flags;
    }

  4. #4
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Salut,
    Oui, une union c'est quand on met plusieurs membres au même emplacement mémoire.
    Ca ne veux pas dire qu'on stock deux informations différente au même endroit. Mais plutôt que selon le contexte une seule des deux information est utile, l'autre n'a pas lieue d'être. Ainsi, plutôt que de faire une structure avec deux membre dont un des deux ne sera jamais utilisé pour une instance donnée, on regroupe ces données "optionnelles" afin de ne pas gaspiller la mémoire.
    Il peux y avoir d'autres raisons d'utiliser les unions mais on part dans des astuces des cas particuliers.

    Le *PMINIDUMP_HEADER n'est pas véritablement un pointeur.
    Si tu regarde bien la déclaration C, tu verra que tu es dans un typedef, autrement dit, une définition de type.
    Après le typedef, le compilateur connais 2 nouveaux type : MINIDUMP_HEADER et PMINIDUMP_HEADER.
    Le premier est une structure contenant les champs indiqués, le second est un pointeur vers une structure contenant les champs indiqués. Cette définition permet de "simplifier" la notation des pointeurs en rendant transparent leurs utilisations dans certains cas. Mais *PMINIDUMP_HEADER n'est aucunement un pointeur, c'est un type de donnée, au même titre que int, long ou char.

    Le RVA est un pointeur sur 32bits d'après MSDN, parfois 64bits dans certaines structures, le type est alors RVA64.
    (dbghelp.h)
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    typedef DWORD RVA;
    typedef ULONG64 RVA64;

    Donc moi je coderai plutot ma structure comme ca :
    Code csharp : 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
     
    [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]
    struct MDMP_UNION_TM
    {
      [System.Runtime.InteropServices.FieldOffset(0)]
      UInt32 Reserved;
      [System.Runtime.InteropServices.FieldOffset(0)]
      UInt32 TimeDateStamp;
    }
     
    public struct MINIDUMP_HEADER
    {
      UInt32 Signature;
      UInt32 Version;
      UInt32 NumberOfStreams;
      IntPtr StreamDirectoryRva; // ou UInt32
      UInt32 CheckSum;
      MDMP_UNION_TM TimeDate_Reserved;
      UInt64 Flags;
    }

    mais bon, vu les champs de l'union, tu peux juste mettre un UInt32 a la place ca sera tout pareil. Par contre il faudrait vérifier s'il ne faut pas déclarer explicitement tout le layout de la structure et non pas juste celui de l'union.


    Edit : Over-grillé, ca m'apprendra à répondre aux questions de mon stagiaire avant de valider mon post

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 103
    Points : 97
    Points
    97
    Par défaut
    Merci à vous deux !
    Effectivement c'est un peu plus clair dans mon esprit concernant le mot clé union en C.
    Merci aussi pour l'explication sur le type RVA.

    Je vais suivre vos conseils et continuer a porter les différentes structures en C#... Et vu le format de fichier des KDMPs... j'ai du pain sur la planche

    Pour l'instant je met le topic en resolved mais il se peut que je revienne vers vous très prochainement

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 103
    Points : 97
    Points
    97
    Par défaut
    Hé voilà je l'avais bien dit ... je suis de retour !

    Voici la définition qui me pose problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct _MINIDUMP_STRING {
    	ULONG32 Length;
    	WCHAR Buffer [0];
    } MINIDUMP_STRING, *PMINIDUMP_STRING;
    Ici je ne comprend même pas la ligne
    C'est quoi exactement cette ligne ? Un pointeur vers un tableau ?
    Parce que une définition de tableau de 0 élément... je n'avais encore jamais vu !

    Merci pour votre aide.
    AlnCool

    EDIT:
    J'ai encore trouvé une définition identique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ULONG32 ExceptionInformation [ 0 ];

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    J'ai testé dans un petit prog C++, la taille de cette structure est de 4 octets. Donc le WCHAR Buffer [0] a une taille de 0... A mon avis tu peux même supprimer ce champ dans ta déclaration C#...

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Février 2005
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 103
    Points : 97
    Points
    97
    Par défaut
    Merci pour ton aide tomlev,

    Mais j'ai un sérieux doute si je le supprime.... sinon la structure n'aurait pas lieu d'être..

    Si je regarde le nom de la structure, elle servirait à indiquer le contenu du message se référant au minidump et donnerai aussi sa longueur. Si la structure ne renseigne que le nombre de caractères .. je trouve ça vraiment bizarre !

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Oui, je vois ce que tu veux dire... à mon avis, ce champ signifie simplement que les données du buffer sont stockées à la suite de la structure. Le champ Buffer te donne donc l'adresse du début du buffer, et le champ Length sa longueur...

    Donc en gros c'est comme si la structure avait une taille variable, ce qu'on ne peut pas modéliser en C#. A priori il va falloir que tu gères à la main la lecture du buffer...

Discussions similaires

  1. besoin d'aide pour le composant DBComboBox
    Par jane2002 dans le forum Bases de données
    Réponses: 8
    Dernier message: 28/02/2004, 19h01
  2. Besoin d'aide avec postgresql sous windows NT
    Par Chihuahua dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/07/2003, 08h29
  3. [CR] besoin d'aide sur les formules
    Par GuillaumeDSA dans le forum Formules
    Réponses: 4
    Dernier message: 10/07/2003, 12h19
  4. [TP]besoin d'aide pour commandes inconnues
    Par Upal dans le forum Turbo Pascal
    Réponses: 15
    Dernier message: 03/10/2002, 10h48
  5. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h05

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