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

  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.

  7. #7
    Membre averti
    Inscrit en
    D�cembre 2006
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : D�cembre 2006
    Messages : 23
    Par d�faut
    ZashOne

    Voici comme demand� la d�claration de la fonction en C:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Error_Context InitImage(const UInt8 *i__imagedata, UInt32 i__imagewidth, UInt32 i__imageheight, SInt32 i__imageresolution, SInt8 i__rank, Image *o__Image);
    dans ton cas tu n as pas besoin d utiliser je pense de Intptr
    J'ai modifi� les param�tres IntPtr pour avoir ceci:
    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(byte[] raw, UInt32 width, UInt32 height, float resolution, int rank, [In, Out] image);
    Lors de l'appel de la fonction Init, je soul�ve l'exception :
    "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
    Voici le code :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    byte[] raw = GetBytes(bmp);
    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 ptrErr = IntPtr.Zero;
    ptrErr = InitImage(raw, (UInt32)bmp.Width, (UInt32)bmp.Height, bmp.HorizontalResolution, rank, img);
    Mais je ne comprends pas pourquoi
    pour tout ZashOne

  8. #8
    Membre �clair�
    Inscrit en
    Juillet 2007
    Messages
    357
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par d�faut
    Image , dans ton api,ca doit etre une structure dont la declaration est fournie avec ton api et pas une classe a mon avis. Poste la egalement.

    de plus dans la declaration de ta fonction , tu as Image *o__Image.

    Donc tu doit envoyer l adresse de ta classe/structure et pas ta Classe/structure. En C#, dans ton dllimport tu doit donc avoir
    et tu appele via

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ptrErr = InitImage(raw, (UInt32)bmp.Width, (UInt32)bmp.Height, bmp.HorizontalResolution, rank, ref img);

  9. #9
    Membre averti
    Inscrit en
    D�cembre 2006
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : D�cembre 2006
    Messages : 23
    Par d�faut
    Image , dans ton api,ca doit etre une structure dont la declaration est fournie avec ton api
    Tout � fait, c'est une structure dont voici la d�claration:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct {
    T__UInt8	*m__imagedata;
    T__UInt32	m__imagewidth;
    T__UInt32	m__imageheight;
    T__UInt32	m__imageresolution;
    T__SInt8	m__rank;
    T__UInt32	m__initok;   
    T__Struct_Type m__structtype;    
    }Struct_Image;
    Je fais un test avec tes remarques et je te tiens au courant

  10. #10
    Membre averti
    Inscrit en
    D�cembre 2006
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : D�cembre 2006
    Messages : 23
    Par d�faut
    Voil�, tout fonctionne presque parfaitement
    Pas d'erreur � la compilation et pas d'exception non plus
    Seul hic , la fonction InitImage ne renvoie pas le bon code d'erreur. Le message que je re�oit m'indique que les dimensions, longueur et largeur, ne sont pas comprises entre 256 et 4096.
    Or je suis certain que c'est le cas puisque mes images font 512*512.
    J'ai m�me essay� avec:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ptrErr = InitImage(raw, 512, 512, bmp.HorizontalResolution, rank, ref img);
    � la place de :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    ptrErr = InitImage(raw, bmp.Width, bmp.Height, bmp.HorizontalResolution, rank, ref img);
    Evidemment, si le code d'erreur n'est pas success, img n'est pas initialis�.
    Le probl�me ne vient de la fonction native non plus car elle est utilis�e par d'autres programmes et l� �a fonctionne.
    Si quelqu'un a une id�e, je suis preneur.


  11. #11
    Membre �clair�
    Inscrit en
    Juillet 2007
    Messages
    357
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par d�faut
    le typedef du T__UInt32 c quoi , tu es sur que c est pas une adresse qu il cherche?

  12. #12
    Membre averti
    Inscrit en
    D�cembre 2006
    Messages
    23
    D�tails du profil
    Informations forums :
    Inscription : D�cembre 2006
    Messages : 23
    Par d�faut
    le typedef du T__UInt32 c quoi
    c'est simplement une red�finition de int32 dans un fichier .h comme montr� ci-dessous :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    #ifdef _WIN32
    typedef unsigned __int32        T__UInt32;
    typedef signed __int32          T__SInt32;
    #else
    typedef unsigned int            T__UInt32;
    typedef signed int              T__SInt32;
    #endif
    tu es sur que c est pas une adresse qu il cherche?
    J'en suis certain.

    Je ne vois malheureusement pas o� se situe le probl�me
    Marshalling ou autre???

    En tout cas ZashOne pour ton aide pr�cieuse

  13. #13
    Membre �clair�
    Inscrit en
    Juillet 2007
    Messages
    357
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 357
    Par d�faut
    si tu envoi 512 pour un int tu recois un int de l autre cot� , vu que il y a des margeur-hauteur dans ta struct a mon avis le probleme se passe la , reli bien la doc de ton api.

    Sinon voila ce que tu peux faire ,
    cree une solution contenant une dll C qui prend et renvoi les meme valeur et en interne appel ton api.
    Ensuite cree une appli mfc ou win32 qui appele cette dll pour valider.
    Pour terminer dans ta solution rajoute une appli .net qui appelera ta dll. Dans les propri�t� de ta solution , tu peux cocher "Allow unmanaged code debug", de la sorte tu verra ce qui se passe un peu mieux.

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