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:
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:
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:
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:
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
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:
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....