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 :

Marshal.PtrToStructure probleme avec les bool


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 5
    Par défaut Marshal.PtrToStructure probleme avec les bool
    Bonjour,

    Je suis en train de tester le passage de structure entre une Dll en C++ (unmanaged) et un programme en C#.

    Je fais quelque chose de très simple pour le moment.

    Ma Dll C++ contient une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
        int      a_;
        int      b_;
        double   c_;
        bool     d_;
    } TestStruct;
    Ensuite, dans une fonction je crée et rempli ma Structure de la manière suivante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void* TestEnvoiDonnee()
    {
        TestStruct *maStruct = (TestStruct*) malloc(sizeof(TestStruct));
        maStruct->a_ = 1;
        maStruct->b_ = (int)false;
        maStruct->c_ = 5.2;
        maStruct->d_ = false;
     
        return maStruct;
    }
    Dans mon code C# j'ai créé une structure du même type afin de récupérer les données avec la fonction Marchal.PtrToStructure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public struct MyStruct
    {
        public int    a_;
        public int    b_;
        public double c_;
        public bool   d_;
    }
    Je récupère ensuite ma structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    IntPtr ptr = TestEnvoiDonnee();
    if (IntPtr.Zero == ptr)
    {
        Console.WriteLine("Probleme de recup du pointeur");
    }
    else
    {
        MyStruct donnee = (MyStruct)Marshal.PtrToStructure(ptr, typeof(MyStruct));
    }
    (Je vous passe le DllImport etc le problème ne vient pas d'ici)

    Et donc le problème c'est que le booleen récupéré dans 'donnee' est toujours à true, je ne sais pas pourquoi. C'est étonnant puisque mon cast de false en int me donne bien 0 lui dans le champ b_.
    Les autres valeurs quant à elles sont correctes.

    Si quelqu'un à une idée ou une piste, j'avoue que la je trouve ça un peu bizarre ^_^

    Merci bien.

    Bonne journée

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Zwart Voir le message
    Si quelqu'un à une idée ou une piste, j'avoue que la je trouve ça un peu bizarre ^_^
    Bizarre en effet mais le bool n'est pas un type qui a une existence "réelle" en C++, c'est une rédéfinition. Ceci explique peut être cela.

    Donc le plus simple, serait de refleter dans la structure C# le type correspondant (int ? short ? à vérifier) quitte à rajouter une propriété à la structure coté C# qui ferait une conversion du contenu vers un bool .net standard.


    Dans le genre :

    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
     
        public struct MyStruct
    {
        public int    a_;
        public int    b_;
        public double c_;
        public int   d_;
     
        public bool D
        {
            get
            {
                return d_ != 0 ? true : false;
            }
        }
    }

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 5
    Par défaut
    Oui effectivement je pense que je vais être obligé de faire quelque chose comme ça, c'est se qui parait être le plus simple et le plus propre.

    Merci bien

    Bonne journée

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Zwart Voir le message
    Oui effectivement je pense que je vais être obligé de faire quelque chose comme ça, c'est se qui parait être le plus simple et le plus propre.
    Fait par ailleurs attention aux alignements (tu peux les piloter finement avec l'attribut StructLayout).

  5. #5
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut MarshalAs(UnmanagedType) comme attribut de type
    bonjour
    Decore dans ta structure
    Helas le type "bool" n'est pas un type "blittable"(type standard comme l'int,double ...).
    Il y a une multiplicite de "Bool" helas.
    Pour eviter de sous-entendre des conversions implicites utilise l'attribut MarshalAs(UnmanagedType) devant chaque membre dans les structures et les classes.

    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
    51
    52
     
    //DOC MSDN C++:  Utiliser 
    //
    // I1 Entier signé sur 1 octet  pour avoir un Boolean sur 1 octet de type C (true = 1, false = 0). 
    //
    // Bool sur 4 octets . type BOOL Win32(true != 0, false = 0). 
    //
    //VariantBool sur 2 octets . type BOOL OLE COM(true !=-1, false = 0). 
    //
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
     
    namespace WindowsFormsApplication1
    {
        public struct MyStruct
        {
     
            //entier 8 octets comme int (4 octes  pour short)
            [MarshalAs(UnmanagedType.I8)]
            public int a_;
            [MarshalAs(UnmanagedType.I4)]
            public int b_;
            //reel 8 octets comme double(4 octets pour float)
            [MarshalAs(UnmanagedType.R8)]
            public double c_;
            //utiliser I1 dans le cas d'un bool Type C(1 octet) dans ton cas
            [MarshalAs(UnmanagedType.I1)]
            public bool d_;
            //utiliserBool dans le cas d'un bool de l'API WIN32(sur 4 octets)
            [MarshalAs(UnmanagedType.Bool)]
            public bool e_;
            //utiliser VariantBool dans le cas d'un bool de l'OLE COM(sur 4 octets)
            [MarshalAs(UnmanagedType.VariantBool)]
            public bool f_;
        }
        public partial class Form1 : Form
        {
     
            public Form1()
            {
                InitializeComponent();
            }
        }
    }
    bon code....

Discussions similaires

  1. Help!! Probleme avec les dates sur SQL SERVER
    Par Nadaa dans le forum MS SQL Server
    Réponses: 16
    Dernier message: 03/08/2006, 16h55
  2. PROBLEME AVEC LES REQUETES IS NULL / NOT EXISTS
    Par sylvaine dans le forum Langage SQL
    Réponses: 5
    Dernier message: 04/06/2004, 13h26
  3. [langage] probleme avec les listes dans des listes
    Par pqmoltonel dans le forum Langage
    Réponses: 7
    Dernier message: 27/04/2004, 12h32
  4. Problem avec les *.AVI sur les panels
    Par NaDiA_SoFt dans le forum C++Builder
    Réponses: 3
    Dernier message: 31/08/2003, 22h50
  5. probleme avec les processus
    Par saidi dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 05/02/2003, 00h18

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