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++/CLI Discussion :

Passage de paramètres


Sujet :

C++/CLI

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 23
    Par défaut Passage de paramètres
    Bonjour tout le monde,

    Dans la dll non managée, j'ai une fonction qui initialise une structure. J'ai donc crée une classe C# qui se rapporte à cette structure et se compose comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [StructLayout(LayoutKind.Sequential)]
    public class ManagedClass
    {
        [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 525420)]
        public byte[] imgData;
        public Int32 imgWidth;
        public Int32 imgHeight;
        public Single imgResolution;
        public sbyte fingerRank;
        public Int32 st;
    }
    Et lorsque j'exécute le code suivant, je constate qu'il y a des différences de valeur à certains indices entre le tableau de bytes que je passe en parametre et celui de ma classe managée.

    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
    [DllImport(@"DllName.dll", EntryPoint = "Init", SetLastError = true)]
    public static extern IntPtr Init(byte[] raw, int width, int height, Single resolution, int rank, int type);
     
    static void Main(string[] args)
    {
        Bitmap bmp= new Bitmap(@"Image.bmp");
        byte[] raw = GetBytes(bmp);
        IntPtr ptr = new IntPtr();
        ManagedClass mc = new ManagedClass();
     
        ptr = Init(raw, bmp.Width, bmp.Height, 500, 3, 111);
        Marshal.PtrToStructure(ptr, mc);
        int i = 0;
        foreach (byte b in mc.imgData)
        {
            if (b != raw[i])
            {
                string str = string.Format("{0:000} \t {1:000} à l'indice {2}", b, raw[i], i);
                Debug.WriteLine(str);
            }
            i++;
     
        }
    }
     
    private static byte[] GetBytes(Bitmap bmp)
    {
        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, ImageFormat.Bmp);
        byte[] b = ms.GetBuffer();
        return b;
    }
    Voici les différences relevées :
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    246 	 076 à l'indice 0
    003 	 004 à l'indice 1
    073 	 080 à l'indice 9
    110 	 114 à l'indice 10
    116 	 110 à l'indice 12
    070 	 116 à l'indice 13
    105 	 081 à l'indice 14
    110 	 117 à l'indice 15
    103 	 097 à l'indice 16
    101 	 108 à l'indice 17
    114 	 105 à l'indice 18
    112 	 116 à l'indice 19
    114 	 121 à l'indice 20
    105 	 058 à l'indice 21
    110 	 069 à l'indice 22
    116 	 082 à l'indice 23
    073 	 082 à l'indice 24
    109 	 058 à l'indice 25
    097 	 032 à l'indice 26
    103 	 073 à l'indice 27
    101 	 110 à l'indice 28
    058 	 112 à l'indice 29
    069 	 117 à l'indice 30
    082 	 116 à l'indice 31
    082 	 032 à l'indice 32
    058 	 115 à l'indice 33
    032 	 116 à l'indice 34
    084 	 114 à l'indice 35
    104 	 117 à l'indice 36
    101 	 099 à l'indice 37
    032 	 116 à l'indice 38
    105 	 117 à l'indice 39
    110 	 114 à l'indice 40
    112 	 101 à l'indice 41
    117 	 032 à l'indice 42
    116 	 105 à l'indice 43
    032 	 115 à l'indice 44
    104 	 032 à l'indice 45
    101 	 110 à l'indice 46
    105 	 111 à l'indice 47
    103 	 116 à l'indice 48
    104 	 032 à l'indice 49
    116 	 105 à l'indice 50
    032 	 110 à l'indice 51
    115 	 116 à l'indice 53
    032 	 105 à l'indice 54
    119 	 097 à l'indice 55
    104 	 108 à l'indice 56
    101 	 105 à l'indice 57
    116 	 122 à l'indice 58
    104 	 101 à l'indice 59
    101 	 100 à l'indice 60
    114 	 046 à l'indice 61
    032 	 010 à l'indice 62
    117 	 000 à l'indice 63
    110 	 000 à l'indice 64
    100 	 000 à l'indice 65
    101 	 000 à l'indice 66
    114 	 000 à l'indice 67
    032 	 000 à l'indice 68
    050 	 000 à l'indice 69
    053 	 000 à l'indice 70
    054 	 000 à l'indice 71
    032 	 000 à l'indice 72
    119 	 000 à l'indice 73
    104 	 000 à l'indice 74
    101 	 000 à l'indice 75
    116 	 000 à l'indice 76
    104 	 000 à l'indice 77
    101 	 000 à l'indice 78
    114 	 000 à l'indice 79
    032 	 000 à l'indice 80
    111 	 000 à l'indice 81
    118 	 000 à l'indice 82
    101 	 000 à l'indice 83
    114 	 000 à l'indice 84
    032 	 000 à l'indice 85
    052 	 000 à l'indice 86
    048 	 000 à l'indice 87
    057 	 000 à l'indice 88
    054 	 000 à l'indice 89
    046 	 000 à l'indice 90
    010 	 000 à l'indice 91
    067 	 080 à l'indice 159
    111 	 114 à l'indice 160
    109 	 105 à l'indice 161
    109 	 110 à l'indice 162
    111 	 116 à l'indice 163
    110 	 081 à l'indice 164
    070 	 117 à l'indice 165
    117 	 097 à l'indice 166
    110 	 108 à l'indice 167
    099 	 105 à l'indice 168
    105 	 121 à l'indice 170
    111 	 046 à l'indice 171
    110 	 099 à l'indice 172
    115 	 112 à l'indice 173
    046 	 112 à l'indice 174
    099 	 000 à l'indice 175
    112 	 000 à l'indice 176
    112 	 000 à l'indice 177
    097 	 223 à l'indice 412
    Quelqu'un peut-il éclairer ma lanterne sur ce problème SVP???
    Merci d'avance!!!

  2. #2
    Membre éclairé
    Inscrit en
    Juillet 2007
    Messages
    357
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par défaut
    a moins que tu en ai vraiment besoin , enlever les attribut

    [StructLayout(LayoutKind.Sequential)]
    et

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 525420)]

    et reteste

  3. #3
    Membre averti
    Inscrit en
    Décembre 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 23
    Par défaut
    Je ne sais pas si j'en ai absolument besoin, mais si je ne les mets pas, j'ai des exceptions qui sont soulevées.

    pour la piste.

  4. #4
    Membre éclairé
    Inscrit en
    Juillet 2007
    Messages
    357
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par défaut
    tu peux toujours essayer ca

    cree une structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public struct ManagedStruct
    {
        public byte[] imgData;
        public Int32 imgWidth;
        public Int32 imgHeight;
        public Single imgResolution;
        public sbyte fingerRank;
        public Int32 st;
    }
    une autre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public struct ManagedStruct_tempon
    {
        public Intptr imgData;
        public Int32 imgWidth;
        public Int32 imgHeight;
        public Single imgResolution;
        public sbyte fingerRank;
        public Int32 st;
    }
    [/CODE]



    ensuite dans ton code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ManagedStruct l_ms;
    l_ms.imdData = new byte[525420];
    ManagedStruct_tempon l_ms_tempon ;
    IntPtr ptr = IntPtr.zero;
    ptr = Init(raw, bmp.Width, bmp.Height, 500, 3, 111);
    Marshal.PtrToStructure(ptr, l_ms_tempon);
    Marshal.Copy( ManagedStruct_tempon.imgData, ManagedStruct.imgData, 
    0,525420 );
    // autre recopie de valeur

  5. #5
    Membre averti
    Inscrit en
    Décembre 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 23
    Par défaut
    Oups, j'avais pas réalisé que c'était le post délesté.

    Depuis, j'ai reçu une nouvelle version de la dll native et donc j'ai dû modifier quelque peu les structures pour qu'elles correspondent aux nouvelles fonctions dont voici la signature d'initialisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [DllImport(@"FPQC.dll", EntryPoint = "InitImage", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr InitImage(IntPtr ptrRaw, UInt32 width, UInt32 height, float resolution, int rank, out IntPtr ptrFpImage);
    Cette fonction retourne une structure de type ErrorContext déclarée comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [StructLayout(LayoutKind.Sequential)]
    public class ErrorContext
    {
        [MarshalAs(UnmanagedType.I4)]
        public T__FPQC_Returned_Code returnedCode;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public String errorMessage;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public String errorFile;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 errorLine;
    }
    La fonction prend en input une série de paramètres dont le dernier est de type out IntPtr qui correspond à ce qui suit:
    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
     
    [StructLayout(LayoutKind.Sequential)]
    public class Image
    {
        [MarshalAs(UnmanagedType.ByValArray)]
        public byte[] imgData;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 imgWidth;
        [MarshalAs(UnmanagedType.U4)]
        public UInt32 imgHeight;
        [MarshalAs(UnmanagedType.R4)]
        public float imgResolution;
        [MarshalAs(UnmanagedType.I1)]
        public sbyte rank;
        [MarshalAs(UnmanagedType.U4)]
        public Int32 initok;
        [MarshalAs(UnmanagedType.I4)]
        public T__FPQC_Struct_Type type;
    }
    Le problème qu'il me reste à résoudre est le passage des paramètres pour que la fonction initialise la structure Image avec l'appel suivant :
    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
     
    byte[] raw = GetBytes(bmp);
    IntPtr ptrRaw = Marshal.AllocHGlobal((Marshal.SizeOf(raw[0])) * raw.Length);
    Marshal.Copy(raw, 0, ptrRaw, raw.Length);
    ErrorContext eContext = new ErrorContext();
    Image img = new Image();
    img.imgData = new byte[raw.Length];
    raw.CopyTo(img.imgData, 0);
    img.rank = (sbyte)rank;
    img.imgHeight = (uint)bmp.Height;
    img.imgWidth = (uint)bmp.Width;
    img.imgResolution = bmp.VerticalResolution;
    img.initok = 123;
    img.type = 111;
    IntPtr ptrImage = Marshal.AllocHGlobal(Marshal.SizeOf(img));
    Marshal.SizeOf(ptrImage));
    IntPtr ptrErr = Marshal.AllocHGlobal(Marshal.SizeOf(eContext));
    ptrErr = InitImage(ptrRaw, (uint)bmp.Width, (uint)bmp.Height, img.imgResolution, img.rank, out ptrImage);
    Marshal.PtrToStructure(ptrErr, eContext);

  6. #6
    Membre éclairé
    Inscrit en
    Juillet 2007
    Messages
    357
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par défaut
    poste la declaration de ta fonction en C maisdans ton cas tu n as pas besoin d utiliser je pense de Intptr , utilise une structure Image a la place de ta classe.

    un petit truc , si tu envoi en param "out" un tableau ou une structure contenant un tableau tu doit declarer le pramaetre dans ta fonction sous la forme

    [In,Out] Image

    Sinon tout se passe bien mais les valeur entre manage et non manage ne sont pas affectée car par default l'interoperatibilité ne le fait pas pour des raisons pas evidentes de performances.

Discussions similaires

  1. [Forms]Passage de paramètre entre Forms et Reports
    Par jack554 dans le forum Reports
    Réponses: 4
    Dernier message: 30/03/2004, 13h58
  2. probleme lors du passage de paramètre
    Par maxmj dans le forum ASP
    Réponses: 4
    Dernier message: 18/11/2003, 00h15
  3. [XSL] Passage de paramètres à un template
    Par pantin dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/06/2003, 13h28
  4. passage de paramètres
    Par pram dans le forum XMLRAD
    Réponses: 5
    Dernier message: 18/02/2003, 17h28
  5. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 19h47

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