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#] Pointeurs et compagnie


Sujet :

C#

  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut [C#] Pointeurs et compagnie
    Bonjour,

    n'étant pas un grand spécialiste de la chose, j'aurais besoin de votre aide sur les pointeurs.
    Voilà le problème:
    j'utilise une DLL faite en Delphi et je dois utiliser une méthode qui prend en parametre une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static extern int MethodeDLL(ref MASTRUCTURE pParam)
    Ma structure étant donc déclaré ainsi pour éviter les problèmes de mémoire que je rencontrais au début:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public unsafe struct MASTRUCTURE
            {
                public fixed byte Membre1[6];
                public fixed byte Membre2[20];
                public fixed byte Membre3[6];
            }
    Dans mon code, j'appelle donc cette méthode. Ma structure est apparement bien initialisée. Et donc si je comprends bien, je me retrouve avec la valeur des pointeurs dans les membres de ma structure. (Membre1, Membre2 et Memebre3 étant de type 'byte*')

    Et mon problème se pose là: Comment retrouver sur quoi pointe ces fameux pointeurs?

    J'espère avoir été clair...

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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par ElBarto38 Voir le message
    Bonjour,

    n'étant pas un grand spécialiste de la chose, j'aurais besoin de votre aide sur les pointeurs.
    Voilà le problème:
    j'utilise une DLL faite en Delphi et je dois utiliser une méthode qui prend en parametre une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static extern int MethodeDLL(ref MASTRUCTURE pParam)
    Ma structure étant donc déclaré ainsi pour éviter les problèmes de mémoire que je rencontrais au début:


    Dans mon code, j'appelle donc cette méthode. Ma structure est apparement bien initialisée. Et donc si je comprends bien, je me retrouve avec la valeur des pointeurs dans les membres de ma structure. (Membre1, Membre2 et Memebre3 étant de type 'byte*')

    Et mon problème se pose là: Comment retrouver sur quoi pointe ces fameux pointeurs?

    J'espère avoir été clair...
    Ta structure m'étonne.
    Tu dis que Membre1/2/3 sont des pointeurs, dans ce cas il devrait être du type IntPtr. D'autant que la il ne sont pas déclarés comme pointeurs mais comme tableaux à taille connue.

    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
     
    public unsafe struct MASTRUCTURE
    {
    public IntPtr Membre1;
    public IntPtr Membre2;
    public IntPtr Membre3;
    }
     
    byte[6] datas = new byte[6];
    MASTRUCTURE ms = new MASTRUCTURE;
     
    // Appel de la fonction qui la remplit
     
    Marshal.Copy(ms.Membre1, datas, 0, 6);

    Donc ici, ms.Membre1 est de type IntPtr puisqu'il s'agit d'un pointeur, et datas est un tableau de 6 byte (comme indiqué dans la structure originale) contenant les données pointées.

  3. #3
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut
    Erreur lors du Marshal.Copy(...)
    * Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
    * à System.Runtime.InteropServices.Marshal.CopyToManaged(IntPtr source, Object destination, Int32 startIndex, Int32 length)
    Dommage, ca me semblait bien parti pourtant
    L'utilisation de pointeurs devrait m'éviter ce genre d'erreurs pourtant non?

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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par ElBarto38 Voir le message
    Erreur lors du Marshal.Copy(...)


    Dommage, ca me semblait bien parti pourtant
    L'utilisation de pointeurs devrait m'éviter ce genre d'erreurs pourtant non?
    On peux voir la déclaration réelle de MASTRUCTURE ? Je parle de la déclaration telle qu'elle est (serait) faite en C.

  5. #5
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut
    En Delphi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MASTRUCTURE = record
       Membre1: Array[0..6-1] of Char;
       Membre2: Array[0..20-1] of Char;
       Membre3: Array[0..6-1] of Char;

  6. #6
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Dans ce que tu montre

    Membre1,2 et 3 sont des tableaux de bytes et non des pointeurs !!

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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par ElBarto38 Voir le message
    En Delphi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MASTRUCTURE = record
       Membre1: Array[0..6-1] of Char;
       Membre2: Array[0..20-1] of Char;
       Membre3: Array[0..6-1] of Char;
    Je connais pas le delphi mais ca ressemble pas a des pointeurs ca.

    Essaye comme ca :
    Code cshap : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    [StructLayout(LayoutKind.Sequential)] // Ca c'est pour indiquer que les membres se suivent en mémoire.
    public unsafe struct MASTRUCTURE
    {
        public fixed byte Membre1[6];
        public fixed byte Membre2[20];
        public fixed byte Membre3[6];
    }
    L'appel de ta méthode remplit les tableaux avec leurs valeurs et non des pointeurs. Membre1 n'est pas un pointeur, c'est directement la valeur : un tableau de 6 Byte.
    Donc mis à part l'ajout de l'attribut StructLayout(LayoutKind.Sequential) (qui n'est peut être meme pas obligatoire), ton code est correcte.

    edit : ca sent le barbecue non ? Qui ose en ce début d'hivers et pas temps de pluie ?

  8. #8
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Quand je vois le machin en Delphi, c'est plus à ça que je pense :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    [StructLayout(LayoutKind.Sequential)]
        public struct MASTRUCTURE
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
            public string Membre1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string Membre2;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
            public string Membre3;
        }
    (string ou byte[], mais un tableau de char c'est un string ...)

  9. #9
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut
    En fait, au départ j'avais bien déclaré ma structure avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
        public fixed byte Membre1[6];
        public fixed byte Membre2[20];
        public fixed byte Membre3[6];
    ...
    mais quand j'essayais de récupérer leur valeur, le compilateur me sortait une erreur du genre "je ne peux convertir du byte* en ....". D'où mon premier message qui parlait de pointeur.

    Mais je vais essayer d'enqueter sur les autres pistes que vous m'avez donnée.
    Merci en tout cas.

  10. #10
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Ouai mais tu as un "fixed" qui sors du nul part et un "unsafe" complètement inutile ...

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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par smyley Voir le message
    Ouai mais tu as un "fixed" qui sors du nul part et un "unsafe" complètement inutile ...
    Non pas tout à fait.
    La syntaxe
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public byte[6] Membre1;
    ne fonctionne pas, le compilo dit que pour donner une taille au tableau, il faut faire un new. Je ne suis pas sur que faire un new dans une structure soit valable, d'autant que ca risque de casser un peux le layout en mémoire non ?
    Du coup, pour palier il faut écrire "public fixed byte Membre1[6];", seulement le mot clef fixed n'est valable qu'en contexte unsafe.

    Ceci-dit, ta solution semble plus adaptée. Je n'ai pas voulu utilisé le string car elle est constituée de char, et le char managé ne fait pas la même taille que le char non managé (16bits au lieu de 8, me trompe-je ?), et comme je ne connaissait pas l'attribut MarshalAs ....

  12. #12
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut
    Citation Envoyé par smyley Voir le message
    Quand je vois le machin en Delphi, c'est plus à ça que je pense :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    [StructLayout(LayoutKind.Sequential)]
        public struct MASTRUCTURE
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
            public string Membre1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string Membre2;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
            public string Membre3;
        }
    (string ou byte[], mais un tableau de char c'est un string ...)
    Alléluia, ca marche!
    Merci beaucoup à tous! Vous venez de mettre fin à 2 jours de calvaire ^^

  13. #13
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Non pas tout à fait.
    La syntaxe
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public byte[6] Membre1;
    ne fonctionne pas, le compilo dit que pour donner une taille au tableau, il faut faire un new. Je ne suis pas sur que faire un new dans une structure soit valable, d'autant que ca risque de casser un peux le layout en mémoire non ?
    Du coup, pour palier il faut écrire "public fixed byte Membre1[6];", seulement le mot clef fixed n'est valable qu'en contexte unsafe.

    Ceci-dit, ta solution semble plus adaptée. Je n'ai pas voulu utilisé le string car elle est constituée de char, et le char managé ne fait pas la même taille que le char non managé (16bits au lieu de 8, me trompe-je ?), et comme je ne connaissait pas l'attribut MarshalAs ....
    C'est exactement çà. En plus, j'avais lu sur MSDN qu'avec "fixed" et "unsafe", je pourrais résoudre certains problèmes liés à la mémoire.

    Et je ne connaissais pas MarshalAs non plus... Mais apparement ca a tout résolu

  14. #14
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Non pas tout à fait.
    Le mot clef fixed ne fait pas ce que tu crois qu'il fait. ça sert à fixer un objet en mémoire, pas à définir une taille fixe ou je sais pas quoi dans une struct. Du coup, le mot clef fixed nécessite en effet le contexte unsafe vu que ça joue avec les pointeurs mais ce n'est pas du tout pour ce genre d'utilisation.

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

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par smyley Voir le message
    Le mot clef fixed ne fait pas ce que tu crois qu'il fait. ça sert à fixer un objet en mémoire, pas à définir une taille fixe ou je sais pas quoi dans une struct. Du coup, le mot clef fixed nécessite en effet le contexte unsafe vu que ça joue avec les pointeurs mais ce n'est pas du tout pour ce genre d'utilisation.
    Non mais je sais a quoi sert le mot clef fixed et je m'en sert relativement régulièrement. Seulement je ne connaissait pas la syntaxe présente dans le premier post. Comme elle passait a la compilation et que je vois mal comment on peux fixer en mémoire la déclaration d'une structure, j'ai bêtement cru que le mot clef fixed pouvais également servir à ca.

  16. #16
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    bah non, là il a juste fixé en mémoire un champ de structure (a priori ...)

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

Discussions similaires

  1. pointeurs
    Par ghost74 dans le forum C
    Réponses: 3
    Dernier message: 14/12/2002, 02h52
  2. Pointeur vers un tableau
    Par Nikos dans le forum C
    Réponses: 3
    Dernier message: 09/12/2002, 00h43
  3. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14
  4. djgpp et pointeurs far -2
    Par elvivo dans le forum Autres éditeurs
    Réponses: 16
    Dernier message: 29/07/2002, 22h43
  5. djgpp et pointeurs far
    Par elvivo dans le forum C
    Réponses: 2
    Dernier message: 13/07/2002, 00h44

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