Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Utilisation de sf::Music depuis une bibliothèque dynamique personnelle  (Lu 3947 fois)

0 Membres et 1 Invité sur ce sujet

Oliveira

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
Hello !

J'ai récemment créé une bibliothèque dynamique (sous Visual C++ 2012) utilisant SFML seulement j'ai un problème avec l'audio. L'erreur survient toujours avec sf::Music, rien d'autre. J'ai pas mal cherché mais je n'ai pas trouvé la source de l'erreur, peut être une mauvaise manipulation de ma part...
Je suis parvenu à écrire un code minimal qui reproduit l'erreur : il s'agit d'un simple lecteur de musique.

Premier cas : m_currentMusic est un sf::Music.

Côté DLL :

CMusicPlayer.hpp
#ifndef CMUSICPLAYER_HPP
#define CMUSICPLAYER_HPP

class DLL_API CMusicPlayer
{
        public:

                void Register(const char* pName, const char* pPath);

                void Play(const char* pName);

                static CMusicPlayer& GetInstance();

        private:

                CMusicPlayer();

                ~CMusicPlayer();

        private:

                static CMusicPlayer ms_instance;

                sf::Music m_currentMusic;
                std::map<const char*, const char*> m_musics;

};

#define MusicPlayer CMusicPlayer::GetInstance()

#endif
 

CMusicPlayer.cpp
#include "DLL.hpp"

CMusicPlayer CMusicPlayer::ms_instance;

CMusicPlayer::CMusicPlayer()
{

}

CMusicPlayer::~CMusicPlayer()
{

}

void CMusicPlayer::Register(const char* pName, const char* pPath)
{
        assert(pName && pPath && m_musics.count(pName) <= 0);

        m_musics[pName] = pPath;
}

void CMusicPlayer::Play(const char* pName)
{
        assert(pName && m_musics.count(pName) > 0);

        m_currentMusic.openFromFile(m_musics.find(pName)->second);

        m_currentMusic.play();
}

CMusicPlayer& CMusicPlayer::GetInstance()
{
        return ms_instance;
}
 

Côté client :

main.cpp
int main()
{
         MusicPlayer.Register("super_musique", "ambiance.ogg");

        MusicPlayer.Play("super_musique");

        return EXIT_SUCCESS;
}
 

Dans ce premier cas, le problème se situe au démarrage de l'application. Il n'y a pas d'erreur mais le thread est bloqué dans le constructeur de CMusicPlayer. Je n'ai pas beaucoup d'information là dessus si ce n'est que l’exécution est coincée dans dsound.dll d'après le débogueur.

Deuxième cas : m_currentMusic devient un pointeur sur sf::Music

Côté DLL :

CMusicPlayer.hpp
#ifndef CMUSICPLAYER_HPP
#define CMUSICPLAYER_HPP

class DLL_API CMusicPlayer
{
        public:

                void Register(const char* pName, const char* pPath);

                void Play(const char* pName);

                static CMusicPlayer& GetInstance();

        private:

                CMusicPlayer();

                ~CMusicPlayer();

        private:

                static CMusicPlayer ms_instance;

                sf::Music* m_currentMusic;
                std::map<const char*, const char*> m_musics;

};

#define MusicPlayer CMusicPlayer::GetInstance()

#endif
 

CMusicPlayer.cpp
#include "DLL.hpp"

CMusicPlayer CMusicPlayer::ms_instance;

CMusicPlayer::CMusicPlayer()
        : m_currentMusic(nullptr)
{

}

CMusicPlayer::~CMusicPlayer()
{
        if (m_currentMusic)
        {
                delete m_currentMusic;
                m_currentMusic = nullptr;
        }
}

void CMusicPlayer::Register(const char* pName, const char* pPath)
{
        assert(pName && pPath && m_musics.count(pName) <= 0);

        m_musics[pName] = pPath;
}

void CMusicPlayer::Play(const char* pName)
{
        assert(pName && m_musics.count(pName) > 0);

        if (m_currentMusic)
        {
                delete m_currentMusic;
                m_currentMusic = nullptr;
        }

        m_currentMusic = new sf::Music;

        m_currentMusic->openFromFile(m_musics.find(pName)->second);

        m_currentMusic->play();
}

CMusicPlayer& CMusicPlayer::GetInstance()
{
        return ms_instance;
}
 

Côté client le main.cpp reste inchangé.

Dans ce deuxième cas, le problème survient à la fermeture de l'application (la musique fonctionne parfaitement). Je reçois le message d'erreur suivant lors du delete de m_currentMusic dans le destructeur de CMusicPlayer :
"an internal OpenAL call failed in SoundSource.cpp <64> : AN_INVALID_OPERATION the specified operation is not allowed in the current state."

Voilà, désolé de la grosse tartine, j'ai essayé d'être le plus clair et précis possible.

Merci d'avance,

Oliveira

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #1 le: Octobre 21, 2013, 07:59:22 am »
Est-ce que la même chose fonctionne si ta classe est intégrée directement au programme plutôt qu'utilisée à travers une bibliothèque ?
Laurent Gomila - SFML developer

Oliveira

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #2 le: Octobre 21, 2013, 12:55:26 pm »
Hello !  :)

Si la classe est directement intégrée au programme, l'application marche parfaitement, que ça soit avec ou sans pointeur pour le sf::Music.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #3 le: Octobre 21, 2013, 01:10:15 pm »
Ta bibliothèque lie SFML statiquement ou dynamiquement ? Est-ce que ton programme est aussi lié à SFML directement ?
Laurent Gomila - SFML developer

Oliveira

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #4 le: Octobre 21, 2013, 01:45:56 pm »
Ma bibliothèque lie SFML dynamiquement, de même pour mon programme.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #5 le: Octobre 21, 2013, 02:08:55 pm »
Donc tu as deux instances de SFML utilisées par ton programme final : l'une dans la DLL, l'autre dans ton exécutable. Ce qui provoque inmanquablement ce genre de problème. Tu n'as donc pas le choix : il faut lier SFML dynamiquement pour qu'elle ne soit physiquement présente qu'à un seul endroit.
Laurent Gomila - SFML developer

Oliveira

  • Newbie
  • *
  • Messages: 12
    • Voir le profil
Re : Utilisation de sf::Music depuis une bibliothèque dynamique personnelle
« Réponse #6 le: Octobre 21, 2013, 02:21:44 pm »
Ah oui d'accord je comprends maintenant, voilà bien une erreur de débutant...

Du coup, si je garde le lien dynamique de SFML dans ma bibliothèque et pas côté client, comment je fais pour ne pas avoir d'erreur de symbole externe non résolu dans mon programme client si je ne peux pas mettre sfml-audio-d.lib;...etc dans les dépendances ?

Ou lier uniquement statiquement SFML dans la DLL ?

En gros, c'est quoi la manière la plus naturelle de faire, j'avoue c'est la première fois que je rencontre ce genre de problème.
« Modifié: Octobre 21, 2013, 02:31:17 pm par Oliveira »