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 :

Accéd dll C via C#


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 22
    Points : 13
    Points
    13
    Par défaut Accéd dll C via C#
    Bonjour,

    Je rencontre une Exception AccesViolation lorsque j'appelle une méthode de la dll c via mon prog en c#.
    La méthode appelée à pour argument une structure composée de plusieurs champs de type Byte[].

    J'ai remarqué que si je passe, à la place de la structure qui cause l'exception, un Byte[] dont la taille est égale à celle de la somme des tailles des champs de ma structure, cela fonctionne mais il faut effectuer un traitement assez chiant pour remplir la stucture avec mon Byte[].

    Voici comment elle déclarée la fonction en C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CPS_InformationsPorteur ( UINT16 NumSession, struct CPS_InfosPorteur PTR pIP, 
    struct CPS_StatusService PTR pStatusService, PUINT16 pEtatCarte);
    En c#
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [DllImport("System\\cpsw32.dll", EntryPoint = "#8", CharSet = CharSet.Ansi)]
            public static extern UInt16 CPS_InformationsPorteur(UInt16 NumSession, ref CPS_InfosPorteur InfosPorteur, ref CPS_StatusService StatusService, ref UInt16 EtatCarte);
    La structure qui cause l'exception:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct CPS_InfosPorteur {
    UINT8 CodeCivilite	[2];
    UINT8 NomPatronym	[27];
    UINT8 NomMarital	[27];
    UINT8 Prenoms	[3][27];
    UINT8 PrenomUsuel	[27];
    UINT8 CodeLangues	[4][2];    
    } CPS_InfosPorteur ;
    En C# j'ai traduit cette structure par:
    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
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct CPS_InfosPorteur 
        {
          public Byte[] CodeCivilite; 
          public Byte[] NomPatronym;
          public Byte[] NomMarital;   
          public Byte[] Prenoms1;  
          public Byte[] Prenoms2;
          public Byte[] Prenoms3;
          public Byte[] PrenomUsuel; 
          public Byte[] CodeLangues1; 
          public Byte[] CodeLangues2;
          public Byte[] CodeLangues3;
          public Byte[] CodeLangues4;
        }
    Je pense qu'il s'agit d'un pb de déclaration au niveau de ma structure.
    Je ne m'explique pas que si je passe une ref vers une structure ne contenant que des Byte[] j'obtiens une Exception alors que si je passe un Byte[] ca passe...
    Je ne comprend pas non plus le fait que passer une ref vers un Byte[] puisse poser des pb. Après tout, cela correspond à un passage par référence ce que fait nativement C# pour la majorité des types !

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    salut

    ne faudrait-il pas que tu ajoutes (mais j'ai plus le mot clé en tete), un attribut qui donne le nombre d'octet de chaque tableau ? il me semblait que cela etait possible et fortement souhaitable

    The Monz, Toulouse

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 22
    Points : 13
    Points
    13
    Par défaut
    Ok mais je ne vois pas comment déclarer cela...

    En suivant les conseils de "tomlev" sur un autre sujet:
    J'ai essayé de faire ça:

    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
     
    CPS_InfosPorteur p = new CPS_InfosPorteur();
    p.CodeCivilite = new Byte[2];
    p.NomPatronym = new Byte[27];
    p.NomMarital = new Byte[27];
    p.Prenoms1 = new Byte[27];
    p.Prenoms2 = new Byte[27];
    p.Prenoms3 = new Byte[27];
    p.PrenomUsuel = new Byte[27];
    p.CodeLangues1 = new Byte[2];
    p.CodeLangues2 = new Byte[2];
    p.CodeLangues3 = new Byte[2];
    p.CodeLangues4 = new Byte[2];
     
    int size = Marshal.SizeOf(p);        // récupère la taille de ton objet
    IntPtr ptr = Marshal.AllocHGlobal(size);  // alloue de la mémoire sur le tas non-managé
    Marshal.StructureToPtr(p, ptr, true); // copie la structure dans le tas non-managé
    La première instruction me renvoie size=44. Est ce normal sachant qu'en ajoutant les tailles des champs j'obtiens 172 ?

    D'autre part, le prog lève une exception "Accessviolation" lors de l'exécution de la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Marshal.StructureToPtr(p, ptr, true)
    Que faire ?

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    par exemple, un truc comme cela ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
       public class MySystemTime 
       {
          [FieldOffset(0)]public ushort wYear; 
          [FieldOffset(2)]public ushort wMonth;
          [FieldOffset(4)]public ushort wDayOfWeek; 
          [FieldOffset(6)]public ushort wDay; 
          [FieldOffset(8)]public ushort wHour; 
          [FieldOffset(10)]public ushort wMinute; 
          [FieldOffset(12)]public ushort wSecond; 
          [FieldOffset(14)]public ushort wMilliseconds; 
       }
    The Monz, Toulouse

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 22
    Points : 13
    Points
    13
    Par défaut
    En essayant avec la déclaration ci-dessous, je me prend une Exception "TypeLoad"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Impossible de charger le type 'ACDMPGate.CPS_InfosPorteur' à partir de l'assembly 'ACDMPGate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null', car il contient un champ objet à l'offset '2' qui n'est pas correctement aligné ou qui est chevauché par un champ non objet.
    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
     [StructLayout(LayoutKind.Explicit, Size = 172 , CharSet = CharSet.Ansi)]
        public class CPS_InfosPorteur
        {
            [FieldOffset(0)]
            public Byte[] CodeCivilite;
            [FieldOffset(2)]
            public Byte[] NomPatronym;
            [FieldOffset(29)]
            public Byte[] NomMarital;
            [FieldOffset(56)]
            public Byte[] Prenoms1;
            [FieldOffset(83)]
            public Byte[] Prenoms2;
            [FieldOffset(110)]
            public Byte[] Prenoms3;
            [FieldOffset(137)]
            public Byte[] PrenomUsuel;   
            [FieldOffset(164)]
            public Byte[] CodeLangues1;
            [FieldOffset(166)]
            public Byte[] CodeLangues2;
            [FieldOffset(168)]
            public Byte[] CodeLangues3;
            [FieldOffset(170)]
            public Byte[] CodeLangues4; 
        }

Discussions similaires

  1. [Débutant] Appel dll C# via VBScript
    Par Pukram dans le forum C#
    Réponses: 4
    Dernier message: 17/11/2011, 08h03
  2. Réponses: 2
    Dernier message: 23/09/2011, 12h15
  3. Réponses: 2
    Dernier message: 13/09/2010, 08h46
  4. Sécuriser un répertoire via une DLL
    Par kazarn dans le forum MFC
    Réponses: 2
    Dernier message: 05/03/2005, 17h33
  5. [SQLServer] Acces simultanés a une BD via ADO dans un dll
    Par corwin_d_ambre dans le forum Bases de données
    Réponses: 4
    Dernier message: 05/11/2004, 15h52

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