我有一个类,我在其中声明一个静态函数。我将此函数注册为另一个库的回调函数。现在,在这个函数中,我将回调数据取消引用到类指针并调用一个特定的非静态成员。
调用成功,控件进入非静态成员函数。但是在我访问同一个类的成员变量的那个函数里面,我得到了一个分段错误。这很奇怪。任何人都可以帮助我解决我所犯的错误和解决方案吗?
以下是代码的外观。
class test
{
int count;
int callback(const char * a, const char *b)
{
print(a);
print(b);
count++; //// HERE IS WHERE I GET THE SEGMENTATION FAULT
}
public:
static int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
test():count(0) {}
~test() {}
Register()
{
registercallback(callbackwrapper);
}
}
答案 0 :(得分:2)
停止使用void * s。你会遇到很多麻烦。
您可能正在对无效对象调用callback()。我不能从你给出的例子中看出来,但这对我来说似乎是这样。我需要看看registercallback()的实现是否确定,但我注意到callbackwrapper()不是一个静态函数,因此调用它就好像它是一个静态函数(我怀疑可能就是这种情况)会发生各种各样的破坏。
答案 1 :(得分:2)
传递给ptr
的{{1}}很可能是无效指针,或者不是类callackwrapper
的对象。调用仍然成功,因为只要您不访问成员变量,类方法就像普通的C ++函数一样。您访问test
的位置是实际取消引用对象的时间,因此是分段错误。
答案 2 :(得分:0)
int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
是会员功能。该成员函数正在查找对其所属对象的引用。也就是说,上面的函数在下面就变成了这样的东西:
int callbackwrapper(test* this, const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
很可能registercallback不希望这里有成员函数。
您可以通过使callbackwrapper
成为静态成员函数来解决此问题:
static int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}
另外,不要忘记:如果您正在与C库接口,这就是您需要回调的原因,请记住要从C调用的函数需要声明为extern "C"
,这将迫使你将该功能移出课堂,并使其成为
extern "C" int callbackwrapper(const char*a, const char *b, void *ptr)
{
test *p = (test *)ptr;
p->callback(a, b);
}