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 :

Appel de dll C++ à partir de C#


Sujet :

C#

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Décembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2012
    Messages : 6
    Points : 5
    Points
    5
    Par défaut Appel de dll C++ à partir de C#
    Bonjour,
    Je réalise un programme en C# qui fait appel à une dll écrite en C++.
    J'utilise donc les InteropServices pour faire la conversion, mais à l'exécution je me prend un AccessViolationException. Je pense que mes MarshalAs sont mauvais.

    Code du programme :
    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
    [Display(ResourceType = typeof(Ressource), Description = "InitAteDescript")]
            public int InitAte(out bool errorOccured, out int errorCode, out StringBuilder errorMsg)
            {
                ResetParamsErrors();
                if (IsInitHalOK())
                {
                    StringBuilder errMsg = new StringBuilder(MaxLenght);
                    try
                    {
                        DllApiInitATE(XmlNodeInitAte, out _errorOccured, out _errorCode, errMsg);
                        _errorMsg.Append(errMsg);
                    }
                    catch (Exception ex)
                    {
                        ExceptionAppel(ex);
                    } 
                }
                ReturnParamsErrors(out errorOccured, out errorCode, out errorMsg);
                return errorCode;
            }
    Code d'appel à la dll C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public const int MaxLenght = 1024;
            ///Return Type: void
            ///pstrXmlNode: wchar_t*
            ///pbErrorOccurred: boolean*
            ///plErrorCode: int*
            ///twcErrorMsg: wchar_t*
            [DllImportAttribute("./LogicalBB.dll", EntryPoint = "LogicalBB_InitATE", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
            [return: MarshalAs(UnmanagedType.AsAny)]
            private static extern void DllApiInitATE([MarshalAs(UnmanagedType.LPWStr), In(), Out()] StringBuilder pstrXmlNode,
                                                     [MarshalAs(UnmanagedType.I1), Out()] out bool pbErrorOccurred,
                                                     [MarshalAs(UnmanagedType.I4), Out()] out int plErrorCode,
                                                     [MarshalAs(UnmanagedType.LPWStr), In(), Out()] StringBuilder twcErrorMsg);
    Le truc, c'est que le errorCode de la dll C++ est un long sur 4 octets en C++, ce qui correspond à un int sur 4 octets en C#. De même, j'utilise le type unmanaged I1 pour le bool, car le type unmanaged.bool est sur 4 octets.
    Le pstrXmlNode est un wchar_t de taille variable récupéré d'un fichier xml, et twcErrorMsg est de taille fixe :1024 caractères.

    J'ai mes pointeurs qui se marchent sur les pieds et je ne vois pas d'où ça vient.
    Quelqu'un peut m'aider svp ?

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Peux-tu poster la signature exacte de la fonction C ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Décembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2012
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Bien sûr, la voilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LogicalBB_DLL_API LogicalBB_InitATE (const wchar_t * pstrXmlNode,bool* pbErrorOccurred, long* plErrorCode, wchar_t twcErrorMsg[1024]);

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Déjà, quand tu as un doute, il vaut mieux ne pas mettre d'attribut MarshalAs, plutôt que d'en mettre un mauvais... le système d'interop se débrouille généralement assez bien tout seul.

    - Le paramètre pstrXmlNode est const, donc pas modifié ; donc tu peux utiliser directement le type string, plutôt que StringBuilder. De plus, puisque ce n'est pas un paramètre de sortie, il ne faut pas d'attribut Out
    - en général il n'est pas nécessaire de mettre les attributs In et Out ; le In est implicite, et le Out est redondant avec le mot-clé out de C#
    - pas la peine de préciser LPWStr si le charset pour la méthode est déjà déclaré comme Unicode
    - UnmanagedType.AsAny a un sens particulier, et ne correspond pas à void. Enlève juste l'attribut MarshalAs, il n'est pas nécessaire

    Au final ça donne ça, si je ne dis pas de bêtise...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            [DllImportAttribute("./LogicalBB.dll", EntryPoint = "LogicalBB_InitATE", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
     
            private static extern void DllApiInitATE(string pstrXmlNode,
                                                     [MarshalAs(UnmanagedType.I1)] out bool pbErrorOccurred,
                                                     out int plErrorCode,
                                                     StringBuilder twcErrorMsg);

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Décembre 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2012
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Bonjour,
    En effet, laisser C# gérer ça marche beaucoup mieux .
    Merci pour ton aide tomlev

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

Discussions similaires

  1. Appeler une DLL C à partir de C#
    Par Yan302 dans le forum C#
    Réponses: 1
    Dernier message: 19/07/2010, 16h16
  2. [JNI] Appeler une DLL Fortran à partir de Java
    Par Graffity dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 13/11/2008, 00h07
  3. Appeler une DLL à partir de MATLAB
    Par swap_nibble dans le forum MATLAB
    Réponses: 0
    Dernier message: 06/02/2008, 12h06
  4. Réponses: 12
    Dernier message: 23/05/2007, 21h40
  5. Appel d'une DLL Win32 à partir d'une appli DOS 16bit
    Par telghali dans le forum Assembleur
    Réponses: 5
    Dernier message: 23/02/2007, 21h42

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