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 :

pointeurs avec fixed & unsafe, utilisation "lourde"


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Avril 2006
    Messages
    90
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 90
    Par défaut pointeurs avec fixed & unsafe, utilisation "lourde"
    Bonjour
    J'essaie depuis quelques jours d'utiliser C# de la façon suivante:

    J'ai créé un type de structure de données que j'ai packé, dans le but que les données soient concomitantes. Ceci dans l'optique de pouvoir filer en référence ce tableau de données à une fonction d'une DLL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public unsafe struct structtest
        {
            public fixed Byte CODECUVE_TCU[6];         
            public UInt16 CODECLIENT_EU;            
            public fixed UInt16 RESERVE_TEU[6];
        } ;
    J'instancie dans ma classe Form une structure de ce type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    namespace NAMESPACE
    {
        public unsafe partial class  MaClasse : Form
        {
             static unsafe structtest m_MaStruct = new structtest();
        }
    }

    Lors de l'utilisation de cette structure dans une méthode de ma classe, je procède de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            private unsafe void MaMethode()
            {
                fixed (Byte* ptrDebut = m_MaStruct.CODECUVE_TCU)
                {
                    fixed (UInt16* ptrCherche = &m_MaStruct.CODECLIENT_EU)
                    {
                        long adresseDeb = (long)ptrDebut;
                        long adresseCherche = (long)ptrCherche;
                        long Offset = adresseCherche - adresseDeb;
                    }
                }
            }
    Cette méthode me permet de pouvoir connaitre l'offset d'une donnée dans ma structure.

    Je butte sur l'utilisation de mon tableau de Byte, je ne sais pas comment m'en servir. (remplir, extraire un élèment..)

    Quand ma structure est instancié directement dans ma méthode, il n'y a pas de souci, mais lorsqu'elle est instancié dans ma classe une erreur de complilation se produit:
    erreur CS1666: Vous ne pouvez pas utiliser des mémoires tampons de taille fixe contenues dans des expressions non fixed. Essayez d'utiliser l'instruction fixed.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            private unsafe void MaMethode()
            {
                structtest m_MaStruct2 = new structtest();
    
                m_MaStruct2.CODECUVE_TCU[1] = 0;
    
                m_MaStruct.CODECUVE_TCU[1] = 0;   //--> marche pas
             }

    Est ce qu'il n'y a pas plus "simple" pour réaliser ce que je souhaite dans la mesure où je vais reproduire ce genre de calcul de façon mutliple dans mon code.

    L’utilisation de mon projet a pour objectif travailler sur une table Modbus.

    Je remercie les autres posts pour les explications sur l'utilisation de fixed et unsafe.


    Résumé des questions:
    1. Commenter utliser les tableaux fixed ?
    2. Comment alléger l’utilisation d'une instance packé avec les pointeurs ?

    Merci

  2. #2
    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
    ouille ouille !

    Quel est le but in fine ?

    1 : Tu veux ecrire du C en Csharp ?

    2 : ou bien tu veux recuperer des structures produites par une dll en C ?

    Dans le premier cas ca ne sert a rien que de s'embrouiller l'esprit
    Dans le deuxieme cas je n'ai pas encore bien regardé car ce que tu decrit ressemble plutot au premier cas

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2006
    Messages
    90
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 90
    Par défaut
    Salut,

    Effectivement, je tente de faire du C avec du C# car je ne vois pas trop d'autre moyen avec C# de faire ce que je voudrai.

    Pour résumer, j'aimerai:

    1. connaitre l'adresse d'un élèment dans une structure.
    Explication avec un exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public unsafe struct structtest
        {
            public fixed Byte CODECUVE_TCU[6];        //Adresse 0 (en octet)
            public UInt16 CODECLIENT_EU;                //Adresse 6 (en octet)
            public fixed UInt16 RESERVE_TEU[6];        //Adresse 8 en octet
        } ;
    Qu'est ce qu'il existe comme méthode CSharpienne pour faire ça ? (pour le moment j'utilise les pointeurs pour déterminer cette adresse)

    2. Je passe à ma DLL (en c++) un pointeur sur cette structure. Cela lui permet de la remplir et ainsi récupérer mes données. Je n'ai donc pas le choix que d'avoir un structure packé et fixed ?

    Merci de t'intéresser à ce sujet.

  4. #4
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Par défaut
    Bonjour, peut etre sans utiliser fixed
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        [StructLayout(LayoutKind.Sequential)]
        public unsafe struct structtest
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.U1)]
            public Byte[] CODECUVE_TCU;        //Adresse 0 (en octet)
            public UInt16 CODECLIENT_EU;                //Adresse 6 (en octet)
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.U2)]
            public UInt16[] RESERVE_TEU;        //Adresse 8 en octet
        } ;
    Je dois avouer que les buffer "fixed" c'est un poil chiant a utiliser

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 62
    Par défaut
    Essaye

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        // On défini nous même l'adresse des variables et la taille de la structure.
        [StructLayout(LayoutKind.Explicit, SizeConst = 20)]
        public unsafe struct structtest
        {
            [FieldOffset(0)]
            public byte* CODECUVE_TCU;
            [FieldOffset(6)]
            public ushort CODECLIENT_EU;
            [FieldOffset(8)]
            public ushort* RESERVE_TEU;
        }
    Tu a ainsi tes deux tableaux et le code client, en espérant que ce soit bon.

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Par défaut
    Citation Envoyé par hussein47 Voir le message
    Essaye

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        // On défini nous même l'adresse des variables et la taille de la structure.
        [StructLayout(LayoutKind.Explicit, SizeConst = 20)]
        public unsafe struct structtest
        {
            [FieldOffset(0)]
            public byte* CODECUVE_TCU;
            [FieldOffset(6)]
            public ushort CODECLIENT_EU;
            [FieldOffset(8)]
            public ushort* RESERVE_TEU;
        }
    Tu a ainsi tes deux tableaux et le code client, en espérant que ce soit bon.
    Ce qui est dommage avec cette facon de faire, c'est que ca oblige a autorisé l'unsafe alors qu'il y a moyen de l'eviter.

Discussions similaires

  1. Problème utilisation de pointeur avec dll
    Par Xarik dans le forum C#
    Réponses: 4
    Dernier message: 05/08/2011, 20h37
  2. Problème de pointeur avec un TQuery
    Par Oluha dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/01/2005, 13h57

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