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 :

Interopérabilité C avec C# et utilisation de structures


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 6
    Par défaut Interopérabilité C avec C# et utilisation de structures
    Bonjour à tous,

    Je suis entrain de m’arracher les cheveux pour utiliser des fonctions définies dans une api C, et je me trouve coincé par le problème suivant :

    Dans mon Api j’ai une fonction qui a le prototype suivant :
    Code C : 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
    /**************** Mon fichier .H********************/
    Int maFonction  (StructRequest *pRequest, StructReponse *pResponse);
    typedef struct
    {
    	SWCHAR	*pData;
    	SWCHAR	Addresse [256+1];
    	SWCHAR	City [100+1];
    	SWCHAR	Country [100+1];
    	SWCHAR	Format [50+1];
    	SWCHAR	*pContext;
    	int		iAlert;
    	int		iRank;
    } StructRequest, *pStructRequest;
     
    typedef struct
    {
    	int				iLastErrorCode;
    	SWCHAR			LastError [1024+1];
    	int				iNbReport;
    	int				iDetectionId;
    	StructReport		*pReport;
    } StructReponse, *pStructReponse;
     
     
    typedef struct
    {
    	int					iRank;
    	SWCHAR				*pData;
    	SWCHAR				ListName [256+1];
    	int					iEntityId;
    	SWCHAR				Remark [1024+1];
    	SWCHAR				Program [128+1];
    	int					iLine;
    	SWCHAR				Title [128+1];
    	int					iNbEntity;
    	StructReportEntity		*pEntity;
    } StructReport, *pStructReport;
     
    typedef struct 
    {
    	SWCHAR	NameType [32+1];
    	SWCHAR	Name [256+1];
    } StructReportEntity, *pStructReportEntity;
     
    /**************** fin du .H**************************/

    Dans mon programme C# je procède comme 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
    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
    103
    104
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    internal class CS_StructReportEntity
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32 + 1)]
        public string NameType;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 + 1)]
        public string Name;
    }
     
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    internal class CS_StructReport
    {
        public int iRank;
        public string pData;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 + 1)]
        public string ListName;
        public int iEntityId;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 + 1)]
        public string Remark;
        [MarshalAs(UnmanagedType.LPWStr, SizeConst = 128 + 1)]
        public string Program;
        public int iLine;
     
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128 + 1)]
        public string Title;
        public int iNbEntity;
        [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] // c'est ici où ca coince ??
        public CS_StructReportEntity[] pEntity;
    }
     
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    internal class CS_StructReponse
    {
        public int iLastErrorCode;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 + 1)]
        public string LastError;
        public int iNbReport;
        public int iDetectionId;
        [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)]
        public CS_StructReport[] pReport;
    }
     
    [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
    internal class CS_StructRequest
    {
     
        public string pData;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 + 1)]
        public string Addresse;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100 + 1)]
        public string City;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100 + 1)]
        public string Country;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50 + 1)]
        public string Format;
        public string pContext;
        public int iAlert;
        public int iRank;
    }
     
     
     
        [DllImport(_CheminAPI)]
        private static extern void maFonction(IntPtr pRequest, IntPtr pResponse);
        public static int CS_maFonction(ref CS_StructReponse Request,
                                                       ref CS_StructRequest Response)
        {
            int retour;
            IntPtr pRequest = Marshal.AllocHGlobal(Marshal.SizeOf(Request));
            IntPtr pResponse = Marshal.AllocHGlobal(Marshal.SizeOf(Response));
            try
            {
                Marshal.StructureToPtr(Request, pRequest, false);
                Marshal.StructureToPtr(Response, pResponse, false);
                retour = maFonction(pRequest, pResponse);
                if (pRequest != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(pRequest, Request);
                }
                else
                {
                    //code
                }
                if (pResponse != IntPtr.Zero)
                {
                    Marshal.PtrToStructure(pResponse, Response);
                }
                else
                {
                    //code
                }
            }
            catch (System.Exception ex)
            {
                //gestion de l’exception            
            }
            finally
            {
                Marshal.FreeHGlobal(pRequest);
                Marshal.FreeHGlobal(pResponse);
     
            }
            return retour;
        }
    Malheuresement ceci ne fonctionne pas avez-vous une idée ? Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    C'est quoi ce type SWCHAR ?

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 6
    Par défaut
    excuse moi j'ai oublié de rajouter cette partie du fichier .H
    #ifdef _UNICODE
    #define SWCHAR wchar_t
    #else
    #define SWCHAR char
    #endif
    dans mon cas c'est wchar_t

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    ben dans ce cas je vois pas trop... tu peux peut-être essayer avec LPTStr à la place de ByValTStr

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 6
    Par défaut
    En fait le probleme ne vient pas du ByValTStr
    j'ai d'autres structures qui fonctionnent comme çà, le probleme vient du pointeur sur un tableau de structures avec une taille variable ([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] // c'est ici où ca coince ??
    public CS_StructReportEntity[] pEntity;
    )

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    En fait je crois que SizeParamIndex ne sert que quand tu appliques l'attribut à un paramètre de méthode.
    Je pense qu'il faut que tu déclares CS_StructReportEntity comme un IntPtr, et que tu récupères le tableau à partir de là

    Sinon tu peux peut-être essayer de faire un CustomMarshaller, mais je sais pas trop comment ça marche...

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 6
    Par défaut
    Tu as raison, effectivement SizeParamIndex n'est utiliser que lorsqu' il est appliquer à un paramètre de la méthode pour indiquer le paramètre qui contient le nombre d'éléments du tableau, mais comme je sèche j'ai essayé de l'utiliser dans ma structure pour voir ce que ça donne , quant à l'utilisation du intPtr je trouve ça un peut lourd surtout que mon tableau peut contenir des centaines de structures.
    je vais voir comment ça fonctionne le "CustomMarshaller" et je vous tiendrai au courant

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/07/2006, 18h19
  2. Pb avec IE en utilisant style.display
    Par sagitarium dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 10/05/2006, 10h44
  3. push_back avec un élément d'une structure
    Par Chewbi dans le forum C++
    Réponses: 5
    Dernier message: 08/04/2006, 14h32
  4. Réponses: 7
    Dernier message: 13/03/2006, 15h39
  5. Réponses: 3
    Dernier message: 09/01/2006, 16h35

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