Search code examples
c++forward-declarationdereference

Can't access object variables passed in a std callback


I have a callback function (ouside my class) which i'm passing a BassMusicPlayer class object as parameter. If do a breakpoint inside it, i can see all the variables and methods in 'self'.

If i try to read/print those values, it won't compile and will give error C2027: use of undefined type 'BassMusicPlayer'. I also added static to the class definition as suggested by others. I could use global variables as a workaround but i really want to avoid doing that.

This is what i have in my class file:

class BassMusicPlayer;
void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user) {
    BassMusicPlayer * self = reinterpret_cast<BassMusicPlayer*>(user);
    //printf("%d\n", self->loop_start);
    //if (!BASS_ChannelSetPosition(channel, self->loop_start, BASS_POS_BYTE))
    if (!BASS_ChannelSetPosition(channel, 0, BASS_POS_BYTE)) // try seeking to loop start
        BASS_ChannelSetPosition(channel, 0, BASS_POS_BYTE); // failed, go to start of file instead
}



class BassMusicPlayer {
private:
    std::string          m_filename;
    int                  m_filetype;
    int                  m_music_handle;
    BassMusicPlayer*     m_music;
    HWND                 m_handle;
    DWORD                m_sample_rate;
    SYNCPROC*            m_callback_proc;

public:
    QWORD loop_start, loop_end;

    // constructor
    BassMusicPlayer(HWND handle, DWORD sample_rate, SYNCPROC* callback_proc) {
        m_handle = handle;
        m_sample_rate = sample_rate;
        m_callback_proc = LoopSyncProc;
    }

    bool OpenMusicFile(std::string filename, QWORD seek_start, QWORD file_length, bool start_playing, bool loop, QWORD loopstart, QWORD loopend) {
        loop_start = loopstart;
        loop_end = loopend;
        m_music_handle = BASS_MusicLoad(false, filename.c_str(), 0, 0, BASS_MUSIC_POSRESET, m_sample_rate);
        BASS_ChannelSetSync(m_music_handle, BASS_SYNC_END | BASS_SYNC_MIXTIME, 0, m_callback_proc, this);
    }
};

Why is my BassMusicPlayer class not being recognized only when i want to access its variables?


Solution

  • Your BassMusicPlayer cannot be recognized because you have this:

    class BassMusicPlayer;
    

    This is called a forward declaration. It tells the compiler that the class BassMusicPlayer exists, but it doesn't tell it what that class is, how much space its objects require, or what members it has. Because pointers are just integers and it doesn't matter what they point to until you try to do something with them, the compiler can use pointers just fine, but the moment you attempt to dereference one of them (such as by accessing its functions or variables with the -> operator), the compiler fails because it doesn't know how to do this. It doesn't find out until the class is actually declared later, after your callback.

    To fix this, move your callback to after the declaration of the class. Because you have to know about the function in your class, you should forward declare the function instead, like this:

    void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user);
    

    The overall order of your code should be:

    • Forward declare the LoopSyncProc function
    • Declare the class
    • Define the LoopSyncProc function