【发布时间】:2014-10-05 16:02:48
【问题描述】:
我目前正在开发一个包含计时器的 SDL_Project。 SDL_Timer 可以有一个回调函数,因为我的计时器位于一个类中,所以这个回调函数是一个静态成员函数,我通过 void*-argument 将“this”传递给它。
但是该类还有另一个成员变量,它是一个指针。但是一旦我调用回调函数,这些指针就不再有效。我想这有点道理,因为静态函数是在另一个线程中调用的。
有没有办法解决这个问题?我对多线程不是很熟悉,所以我不知道要寻找什么。
这是我正在做的事情的基本表示,虽然这个例子工作得很好,因为如果我的理论是正确的,它就在一个线程中。
//A is just an interface so that B can hold a pointer to it
class A
{
public:
virtual int get() = 0;
};
class C
{
public:
C(){};
C(A* parent_arg)
{
parent = parent_arg;
}
void (*fptr)(C* sender) = nullptr;
static void callback(void* param)
{
//In my actual program, me has lost its parent pointer
C* me = (C*)param;
me->fptr(me);
};
//In my actual code, this function is from a SDL_Timer and
//runs in another thread
void Go()
{
callback(this);
}
A* parent = nullptr;
};
class B : A
{
public:
B()
{
c.parent = this;
};
virtual int get() { return myint; };
C c;
private:
int myint = 5;
};
void myfun (C* sender)
{
std::cout << sender->parent->get() << "\n";
};
int _tmain(int argc, _TCHAR* argv[])
{
B b;
b.c.fptr = myfun;
b.c.Go();
int test;
std::cin >> test;
return 0;
}
编辑:
这里有一些关于我在创建 C 和 B 之后如何处理它们以及如何在实际程序中实现它们的更多信息。 所涉及的所有类都是可复制构造的。而 B 中的成员变量 c 在 boost::stable_vector 中。因为对于其他任务,这一切都很好,我假设我的复制构造函数和赋值运算符都可以。 如果我在回调中检查 me 的值,事实证明 me 本身仍然具有所有值,除了指针。
编辑2:
我发现了问题。我复制 B 对象时没有更新父指针。谢谢大家的帮助。
【问题讨论】:
-
在创建线程时如何将成员函数绑定到它的实际实例?
-
你的意思是这样吗?
std::function<Uint32(Uint32, void*)> t = std::bind(this->callback, std::placeholders::_1, std::placeholders::_2); l_timer = SDL_AddTimer(l_delay, t, this);?在这里,我收到“无法从 SDL_Callback 转换为 std::function”错误。 -
SDL_Callback是否允许用户定义的额外参数void*?否则,将 this 绑定到特定类实例的机会很低,应该从线程内调用其成员函数。 -
SDL_Callback 期望回调函数为
Uint32 callback (Uint32, void*)您是说额外的 void* 吗?那么不,但我不能使用一对吗?如果是这样,我该怎么办? -
好的,处理这个问题的最好方法是拥有一个静态类方法,它需要一个指向
class C的指针。然后在void argument中传递一个指向C的有效实例的指针。在回调函数中,将void*的值转换为C*,调用C::mystatic_callback()并将C*作为参数传递。然后你就可以调用C的任何类成员函数了。
标签: c++ multithreading callback