2

我想包装(Facade Pattern)Allegro 对线程的使用,即我install_int_ex(void (__cdecl*)(void), int tick);编写remove_int(void (__cdecl*)(void))的​​一个使用模板user-defined Functor Objects的类,并在创建和销毁类时安装中断和删除中断。

我不断收到编译器错误:error C2664: 'install_int_ex' : cannot convert parameter 1 from 'void (__thiscall [User-defined FunctorName Here]::* )(void)' to 'void (__cdecl *)(void)'和类似的remove_int(void (__cdecl*)(void))

如果被调用的函数接受指向用户数据的指针,这似乎可行void*

不幸的是,Allegro 没有这么灵活。有没有办法绕过这个限制,或者我将不得不使用 Windows CreateThread(并在这个过程中学习线程“真正的方式”)?

另请参阅:使用 C++ 成员函数作为线程的入口点函数

4

2 回答 2

4

这是不可能的。这是预期的函数类型(忽略__cdecl):

void (*)(void);

它不带任何参数。如果这是 C++ 中的非静态成员函数,那么会有一个隐式this参数,但这是 C。如果你想将参数传递给你的函数(包括隐式this参数),你不能这样做。

您可以使用全局变量来传递函子(错误),或者只使用线程。

然而,

请注意install_int_ex( source ) 的 allegro 文档:

但是,您应该知道,它将在中断上下文中调用,这对您可以在其中执行的操作施加了很多限制。它不应该使用大量的堆栈,它不能对操作系统进行任何调用,不能使用 C 库函数,或者包含任何浮点代码,并且它必须非常快速地执行。

中断上下文是一件危险的事情,它与线程不同,你不应该C ++ 代码放在中断上下文中,除非你非常擅长弄清楚你的 C++ 代码做了什么。

不要将 C++ 函数传递给install_int_ex. (同样,除非您确切地知道什么库调用了您的 C++ 代码,或者没有。)

一般来说,学习如何编写在中断中运行的代码比学习如何编写多线程代码更难。中断以线程不会的方式对库函数造成严重破坏,并且在众所周知的程序中存在许多由信号处理程序中的细微错误引起的安全漏洞和错误。

于 2012-06-21T01:11:35.540 回答
0

您正在传递类 AlarmFunctionObject 的非静态成员函数。尝试将成员函数声明为静态。如果您需要访问实际的 AlarmFunctionObject,则必须传递一个静态函数,该函数在该范围内可以访问的某个对象上调用其中的非静态成员函数

class AlarmFunctionObject
{
public:
    static void func()
    {
        someInstanceOfAlarmFunctionObject->myMemberAFunc();
    }
    void myMmberFunc()
    {
        // do stuff
    }
};

并通过 AlarmFunctionObject::func 而不是 myMemberFunc

于 2012-06-21T00:54:43.307 回答