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 :

Appel DLL C++ avec le CRL 2.0


Sujet :

C++/CLI

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut Appel DLL C++ avec le CRL 2.0
    Bonjour à tous,

    Je vous explique mon problème :

    J'ai une DLL en C++, LibFlac permettant de traiter les fichiers audio FLAC (http://www.rarewares.org/files/lossl...-1.3.1-icl.zip), que j'exploite à l'aide d'une autre librairie que voici :
    https://code.google.com/p/practicesharp/

    Le problème, c'est qu'en utilisant la DLL "NaudioFLAC" (de practicesharp) sur un projet utilisant le .NET 4.0 et 4.5 par exemple, j'ai une erreur un peu bizarre sur un appel à la DLL C++.
    Or, si je change le framework en 3.5, utilisant bien le CLR 2.0 tout fonctionne correctement.

    Ma question est, comment forcer l'utilisation du .NET 3.5 (CLR 2.0) juste pour la DLL NAudioFLAC tout en gardant mon projet en .NET 4.0 ?
    J'ai trouvé une solution disant de mettre ça dans le fichier app.config :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
    mais ça ne fonctionne pas.


    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    j'ai une erreur un peu bizarre
    :bouledecristal:

    Je ne sais plus trop quelles sont les difficultés exactes pour les interactions entre DLLs prévues pour différentes versions du framework (ou pire, les DLLs prévues pour interagir avec deux versions différentes d'une même DLL).
    Je dirais au pire, si tout le reste échoue, faire du out-of-process avec WCF...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    :bouledecristal:

    Je ne sais plus trop quelles sont les difficultés exactes pour les interactions entre DLLs prévues pour différentes versions du framework (ou pire, les DLLs prévues pour interagir avec deux versions différentes d'une même DLL).
    Je dirais au pire, si tout le reste échoue, faire du out-of-process avec WCF...

    c'est vrai que j'ai pas précisé je pensais pas ça utile, j'imagine que personne ici n'a déjà utilisé cette librairie, mais voici l'erreur :

    "FLAC: Could not process single!"

    Sur cette fonction à priori :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [DllImport(DLLName, CallingConvention = CallingConvention.Cdecl)]
            public static extern bool FLAC__stream_decoder_process_single(IntPtr context);
    Pour la solution WCF c'est pas envisageable malheureusement, étant donné la perte de performance...

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce message d'erreur, est-il visible dans le code qui appelle cette fonction, ou bien vient-il de la fonction elle-même?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Non à vrai dire ce message n'est pas d'une grande utilité, je vous montre d'où il provient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FLACCheck(
                            LibFLACSharp.FLAC__stream_decoder_process_single(m_decoderContext),
                            "process single");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            private void FLACCheck(bool result, string operation)
            {
                if (!result)
                    throw new ApplicationException(string.Format("FLAC: Could not {0}!", operation));
            }
    Donc ça ne vient pas de la DLL C LibFlac.

    D'ailleurs quand on regarde la doc, c'est pas détaillé du tout.

    https://xiph.org/flac/api/group__fla...122cf7f987f856

    Return values
    FLAC__bool false if any fatal read, write, or memory allocation error occurred (meaning decoding must stop), else true; for more information about the decoder, check the decoder state with FLAC__stream_decoder_get_state().

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Peut-être qu'il faut aussi se poser la question de savoir pourquoi l'appel à cette fonction marche avec le CLR 2.0, et pas avec le 4.0 ? J'ai toujours lu partout que le CLR 4.0 était rétrocompatible avec le 2.0...

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 492
    Par défaut
    j'ai une erreur un peu bizarre sur un appel à la DLL C++.
    Pouvez-vous être un peu plus précis ?

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Pouvez-vous être un peu plus précis ?
    Oui je la décris juste en dessous dans un de mes messages

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 492
    Par défaut
    Oups, quelques messages de loupés.
    Comme il s'agit d'Open-Source, le débugging dans les sources de la bibliothèque pourrait nous donner de précieux complément d'informations, non ?

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Oups, quelques messages de loupés.
    Comme il s'agit d'Open-Source, le débugging dans les sources de la bibliothèque pourrait nous donner de précieux complément d'informations, non ?
    Oui tout à fait, j'essaye depuis plusieurs jours de trouver l'origine de l'erreur, en vain.

    Voici les sources si quelqu'un se sent de déboguer :

    https://github.com/xiph/flac
    Il faut à priori utiliser nasm pour compiler, et également une lib d'ici :
    https://github.com/xiph/ogg

    Je pense que le problème doit venir du callback (stream_decoder.c > ligne 2976 ?) entre la DLL C et le client (.NET), sauf que je ne vois pas où ça capote.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2008
    Messages : 98
    Par défaut
    Je vous met ici les bouts de code concernés, peut-être que certains ici seraient en mesure de dire si le CLR 4.0 l'interprète différemment du 2.0 etc
    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
            private void FLAC_WriteCallback(IntPtr context, IntPtr frame, IntPtr buffer, IntPtr clientData)
            {
                // Read the FLAC Frame into a memory samples buffer (m_flacSamples)
                LibFLACSharp.FlacFrame flacFrame = (LibFLACSharp.FlacFrame)Marshal.PtrToStructure(frame, typeof(LibFLACSharp.FlacFrame));
     
                if (m_flacSamples == null)
                {
                    // First time - Create Flac sample buffer
                    m_samplesPerChannel = flacFrame.Header.BlockSize;
                    m_flacSamples = new int[m_samplesPerChannel * m_flacStreamInfo.Channels];
                    m_flacSampleIndex = 0;
                }
     
                // Iterate on all channels, copy the unmanaged channel bits (samples) to the a managed samples array
                for (int inputChannel = 0; inputChannel < m_flacStreamInfo.Channels; inputChannel++)
                {
                    // Get pointer to channel bits, for the current channel
                    IntPtr pChannelBits = Marshal.ReadIntPtr(buffer, inputChannel * IntPtr.Size);
     
                    // Copy the unmanaged bits to managed memory
                    Marshal.Copy(pChannelBits, m_flacSamples, inputChannel * m_samplesPerChannel, m_samplesPerChannel);
                }
     
                lock (m_repositionLock)
                {
                    // Keep the current sample number for reporting purposes (See: Position property of FlacFileReader)
                    m_lastSampleNumber = flacFrame.Header.FrameOrSampleNumber;
     
                    if (m_repositionRequested)
                    {
                        m_repositionRequested = false;
                        FLACCheck(LibFLACSharp.FLAC__stream_decoder_seek_absolute(m_decoderContext, m_flacReposition), "Could not seek absolute: " + m_flacReposition);
                    }
                }
            }

    Dans le constructeur de la classe on a ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_writeCallback = new LibFLACSharp.Decoder_WriteCallback(FLAC_WriteCallback);
    La déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private LibFLACSharp.Decoder_WriteCallback m_writeCallback;
    Le delegate :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void Decoder_WriteCallback(IntPtr context, IntPtr frame, IntPtr buffer, IntPtr userData);

    Voilà pour le callback du coté de la classe C#. Après recherche j'ai pu constater que le FLAC_WriteCallback ne retourne pas ce qu'il devrait, à savoir "FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE", comme montré ici dans le code en C de la librairie FLAC :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) return false;
    J'ai vérifié en testant, en .NET 3.5 on a bien FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, et en 4.0 on a des chiffres aléatoires (valeur d'un pointeur ?). Le problème est donc directement lié à la valeur retournée par le callback, sauf que je ne vois pas où c'est géré en fait


    Merci pour votre aide !

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

Discussions similaires

  1. Appel DLL C++ avec le CRL 2.0
    Par AliHome dans le forum Framework .NET
    Réponses: 1
    Dernier message: 03/06/2015, 15h13
  2. Réponses: 2
    Dernier message: 19/05/2009, 10h53
  3. [WinCE5.0] Dll-Appel de fonction avec pointeur
    Par Bart_lx dans le forum Windows
    Réponses: 11
    Dernier message: 11/12/2007, 11h43
  4. Erreur lors de l'appel d'une DLL créée avec Visual
    Par WELCOMSMAIL dans le forum C++Builder
    Réponses: 6
    Dernier message: 06/09/2006, 15h53
  5. appel DLL C++ en Delphi (pb avec type)
    Par fkerbourch dans le forum Langage
    Réponses: 7
    Dernier message: 11/07/2005, 17h31

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