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

Langage C++ Discussion :

Comme Appeler une fonction CALLBACK dans une classe


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Novembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2012
    Messages : 15
    Par défaut Comme Appeler une fonction CALLBACK dans une classe
    Bonjour,

    j'ai développé une DLL qui me permet de faire appel à des fonctions d'un DLL spécialisée dans le traitement audio (bass.dll). La première version de ma DLL fonction correctement mais ne fait pas appel à des classes. Notamment l'appel à la fonction Callback depuis la fonction SynchroPlaylist

    Maintenant, je souhaite faire évoluer ma DLL et créer une classe Play_list. Tout semble Ok à l'exception du passage en paramètre de la fonction Callback dans la fonction SynchroPlaylist. J'ai bien lu dans certains forum que la technique à mettre en oeuvre est particulière mais mon niveau en C++ et POO ne m'a pas permis de saisir toutes les subtilités.

    Afin que vous puissiez m'aider à trouver une solution je vous joins le code en question en question. En fait, je ne sais pas :
    - quelle syntaxe utiliser pour faire l'appel de la callback et passer le paramètre à la fonction appelante.
    - si un fonction callback peut faire partie d'une classe.

    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
     
    #include "stdafx.h"
    #include "bass.h"
    #include "bassmix.h"
    #include <sstream> 
    #include <string>  
    #include <iostream>
    #include <random>
    #include <time.h>
     
     
    class Play_list {
     
    private:
    	int rand_a_b(int a, int b);
    	int* init_tableau(int a, int b);
    	void melanger(int* tableau, int taille);
    	std::string new_file_audio(std::string P_playlist, char P_separateur);
    	void CALLBACK SyncProc(HSYNC handle, DWORD channel, DWORD data, void *user);
     
    	std::string m_liste_fichier_audio;
    	int m_nombre_fichier_audio; // Nombre total de fichiers audio dans la play list
    	int* m_tab_playlist; // Tableau d'ordre de lecture de la playlist
    	int cpt_tab; // Position interne de parcours de la playlist
     
    public:
    	void SynchroPlaylist(DWORD P_HDMixer, DWORD P_Flags, QWORD P_Param, DWORD P_Nb_File_audio, const char *P_PlayList, DWORD P_len_char, BOOL P_Lect_alea);
    	int m_position_actuelle; // Position actuelle de lecture dans le tableau	
     
    	DWORD m_mixer;
    	DWORD m_source;
     
    };
     
    ....
    .....
     
    // FUNCTION DE CALLBACK SPECIFIQUE BASS
    //-------------------------------------
    void CALLBACK Play_list::SyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
    {
    	HSTREAM l_next_stream=0;
    	BOOL L_Return;
     
    	std::string l_fic_audio = new_file_audio(m_liste_fichier_audio,';');
     
    	l_next_stream = BASS_StreamCreateFile(false,l_fic_audio.c_str(),0,0,BASS_STREAM_DECODE|BASS_SAMPLE_FLOAT);
    	L_Return = BASS_Mixer_StreamAddChannel(m_mixer, l_next_stream, BASS_STREAM_AUTOFREE|BASS_MIXER_NORAMPIN);
    	L_Return = BASS_ChannelSetPosition(m_mixer,0,BASS_POS_BYTE);
    }
     
    void Play_list::SynchroPlaylist(DWORD P_HDMixer, DWORD P_Flags, QWORD P_Param, DWORD P_Nb_File_audio, const char *P_PlayList, DWORD P_len_char, BOOL P_Lect_alea)
    {
     
    	srand(time(NULL));
    	m_liste_fichier_audio = P_PlayList;
    	m_nombre_fichier_audio = P_Nb_File_audio;
    	m_tab_playlist=init_tableau(1,P_Nb_File_audio);
     
    	...
     
    	std::string First_Fic_Audio = new_file_audio(m_liste_fichier_audio,';');
     
    	m_mixer = BASS_Mixer_StreamCreate(44100,2,BASS_MIXER_END);
     
    	BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,Play_list::SyncProc,0);
     
    	m_source = BASS_StreamCreateFile(false,First_Fic_Audio.c_str(),0,0,BASS_STREAM_DECODE|BASS_SAMPLE_FLOAT);  //1st file open	
    	BASS_Mixer_StreamAddChannel(m_mixer,m_source,BASS_STREAM_AUTOFREE);
     
    }
    Même si je retire Play_list:: devant SynProc dans le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,Play_list::SyncProc,0);
    une erreur est générée par le compilateur (qui est VS 2012)

    Par avance merci de vos retours et de votre aide
    Cordialement
    Fabien

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    On veut bien t'aider, mais... quel est le message d'erreur?

    ca ne serait pas "il manque un &"?

    essaie BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&Play_list::SyncProc,0);

  3. #3
    Membre averti
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Novembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2012
    Messages : 15
    Par défaut
    Citation Envoyé par leternel Voir le message
    On veut bien t'aider, mais... quel est le message d'erreur?

    ca ne serait pas "il manque un &"?

    essaie BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&Play_list::SyncProc,0);
    Tu as raison, je vais préciser les messages d'erreur retournés par la compilateur.
    Pour le & j'avais déjà fais l'essai, ça ne convient pas. Voici :

    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&Play_list::SyncProc,0);Message d'erreur : error C2664: 'BASS_ChannelSetSync' : impossible de convertir le paramètre 4 de 'void (__stdcall Play_list::* ) (.....)' en 'SYNCPROC (__stdcall *)'

    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&SyncProc,0);Message d'erreur : error C2276: '&' : opération non conforme sur l'expression d'une fonction membre.

    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,SyncProc,0);Message d'erreur : error C3867: &'Play_list::SyncProc' : liste d'arguments manquante dans l'appel de fonction ; utilisez 'Play_list::SyncProc' pour créer un pointeur vers membre.

    Je n'arrive pas à trouver la bonne syntaxe. Par contre, j'ai lu dans un billet sur internet que le fait qu'une fonction soit static ou non pouvait jouer. Qu'en passez-vous?
    Sans aucune certitude, je vais poursuivre mes investigations dans cette direction.

    Cordialement.

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par défaut
    Non testé , mais

    Soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Play_list {
    // ...
     
        typedef void (Play_list::* FUNC_PTR) (DWORD, DWORD, QWORD, DWORD, const char*, DWORD, BOOL);
     
    // ...
     
        void CALLBACK SyncProc(HSYNC handle, DWORD channel, FUNC_PTR data, void *user);
     
    // ...
     
    };

    Soit avec avec un cast, mais cela ne va pas marcher parce que ton pointeur va être tronqué en DWORD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    BASS_ChannelSetSync(m_mixer, BASS_SYNC_END | BASS_SYNC_MIXTIME, 0, (DWORD) &Play_list::SyncProc, 0);

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Citation Envoyé par flesenne Voir le message
    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&Play_list::SyncProc,0);;
    Message d'erreur : error C2664: 'BASS_ChannelSetSync' : impossible de convertir le paramètre 4 de 'void (__stdcall Play_list::* ) (.....)' en 'SYNCPROC (__stdcall *)'

    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,&SyncProc,0);.
    Message d'erreur : error C2276: '&' : opération non conforme sur l'expression d'une fonction membre.

    BASS_ChannelSetSync(m_mixer,BASS_SYNC_END|BASS_SYNC_MIXTIME,0,SyncProc,0);.
    Message d'erreur : error C3867: &'Play_list::SyncProc' : liste d'arguments manquante dans l'appel de fonction ; utilisez 'Play_list::SyncProc' pour créer un pointeur vers membre.
    Dans les cas 2 et 3, c'est de la syntaxe, le compilateur te dit, en résumé, que tu exprimes mal un pointeur de fonction membre.

    Cas 1: impossible de convertir le paramètre 4 de 'void (__stdcall Play_list::* ) (.....)' en 'SYNCPROC (__stdcall *)'
    Ca, c'est la vrai faute: relative au sens.
    Impossible de convertir un "pointeur de fonction membre de Play_list retournant void" en pointeur de fonction libre retournant SYNCPROC.
    La seule solution, de fournir un pointeur de fonction libre, ou de changer la fonction BASS_ChannelSetSync.

    Une fonction static vaut une fonction libre, car la classe/structure ne lui sert que de namespace (et de privauté)

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Je suis sûr que c'est quelque part dans la FAQ, mais bon:

    Le prototype de tes fonctions callback contient un void* user, c'est précisément ce dont tu as besoin:
    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
    typedef int (*FONCTION_CALLBACK)(int param1, int param2, void* user)
     
    void FonctionQuiPrendUnCallback(char const *param1, FONCTION_CALLBACK pCallback, void * user);
     
    class MaClasse
    {
    	int MonCallback(int param1, int param2)
    	{
    		//blabla
    	}
    public:
    	static int SMonCallback(int param1, int param2, void* user)
    	{
    		MaClasse * pObj = static_cast< MaClasse * >(user);
    		return pObj->MonCallback(param1, param2);
    	}
    };
     
    ...
     
    int main(void)
    {
    	MaClasse obj;
    	FonctionQuiPrendUnCallback("toto", MaClasse:SMonCallback, &obj);
    }
    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.

  7. #7
    Membre averti
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Novembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2012
    Messages : 15
    Par défaut
    Merci à tous pour vos retours.
    Ils m'ont permis de trouver la solution. Pour info, c'est la solution exposée par Médinoc qui était la réponse à ma problématique. Il faut effectivement passer this dans le paramètre "void* user" de la callback et adapter le contenu de la fonction.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/07/2013, 20h49
  2. appeler une fonction php dans une fonction javaScript
    Par geeksDeve dans le forum Langage
    Réponses: 3
    Dernier message: 17/04/2012, 15h30
  3. Réponses: 8
    Dernier message: 05/04/2011, 08h06
  4. Réponses: 10
    Dernier message: 14/03/2009, 13h36
  5. Réponses: 1
    Dernier message: 25/10/2007, 21h25

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