无法访问在 std 回调中传递的对象变量
Can't access object variables passed in a std callback
我有一个回调函数(ouside我的类),我将传递一个BassMusicPlayer类对象作为参数。如果在里面做一个断点,我可以看到self中的所有变量和方法。
如果我尝试读取/打印这些值,它将不会编译,并将给出错误C2027:使用未定义的类型">BassMusicPlayer"。我还按照其他人的建议在类定义中添加了static。我可以使用全局变量作为一种变通方法,但我真的想避免这样做。
这是我在课堂文件中的内容:
class BassMusicPlayer;
void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user) {
BassMusicPlayer * self = reinterpret_cast<BassMusicPlayer*>(user);
//printf("%dn", 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);
}
};
为什么只有当我想访问BassMusicPlayer类的变量时,它才会被识别?
您的BassMusicPlayer无法识别,因为您有以下内容:
class BassMusicPlayer;
这被称为正向声明。它告诉编译器类BassMusicPlayer
存在,但它不告诉它该类是什么,它的对象需要多少空间,或者它有什么成员。因为指针只是整数,在你尝试使用它们之前,它们指向什么并不重要,编译器可以很好地使用指针,但当你试图取消引用其中一个指针时(例如用->
运算符访问其函数或变量),编译器会失败,因为它不知道如何做到这一点。直到稍后真正声明该类,在回调之后,它才会发现。
要解决此问题,请将回调移动到类声明后的。因为您必须了解类中的函数,所以应该转发声明函数,如下所示:
void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user);
代码的总体顺序应该是:
- 转发声明LoopSyncProc函数
- 声明类
- 定义LoopSyncProc函数
在定义LoopSyncProc
的代码中,您只声明了BassMusicPlayer
。您已经告诉编译器:"存在一个名为BassMusicPlayer
的类",仅此而已。
您可以将指针指向前向声明的类,但不能访问对象本身——此时编译器对对象的类或如何访问它一无所知
您需要将LoopSyncProc
移动到BassMusicPlayer
之下。为此,您需要转发声明LoopSyncProc
:
void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user);
class BassMusicPlayer {
...
};
void __stdcall LoopSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user) {
BassMusicPlayer * self = reinterpret_cast<BassMusicPlayer*>(user);
//printf("%dn", 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;
)不是完整的定义。
解决方案是移动函数定义,使整个类定义已经在作用域中。
- 你能重载对象变量名本身返回的内容吗
- 为什么我可以使用 memcpy 将一个对象变量复制到另一个对象变量
- 如何使用std::lower_bound比较对象变量,而不使用第二个对象进行比较
- 将私有对象变量与用户输入的变量进行比较
- 具有已定义操作重载的 C++ 非类型化值对象/变量库
- 如何对对象数组进行排序,而不考虑对象变量类型
- 在功能中设置对象变量
- 如何创建对象变量,以便每次分配新的指针
- C++ FileIO 以读取和写入对象变量
- 私下声明的对象变量的突变器/访问器方法
- C++ 列表中的对象变量在迭代过程中不会更新
- 稍后使用私有对象变量时如何初始化数组(初始化对象后)
- 通过向量更改对象变量的值
- C 全局对象变量内存释放
- 基本数据类型变量 VS 对象变量
- C 复制分配运算符,用于参考对象变量
- c++从列表中移除元素,并将其分配给对象变量
- 我们是否需要在C++中同步局部对象变量
- 点运算符和箭头运算符之间的区别 结构对象变量 在 C 或 C++ 中创建树
- 无法访问在 std 回调中传递的对象变量