如何使用Functor调用C函数,该函数需要指向C ++中的void函数的指针?

时间:2012-06-21 00:46:43

标签: c++ c function-pointers allegro

我想包装(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))

类似

This seems to work provided the called function accepts pointers to void*user data

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

另请参阅:Using a C++ Member Function as the Thread's Entry-Point-Function

2 个答案:

答案 0 :(得分:4)

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

void (*)(void);

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

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

然而,

请注意install_int_exsource)的allegro文档:

  

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

中断上下文是危险的, 与线程相同,你应该将C ++代码放入中断除非你非常善于弄清楚你的C ++代码是做什么的,否则上下文。

不要将C ++函数传递给install_int_ex(同样,除非您知道完全哪些库调用您的C ++代码是否正在制作。)

通常,学习如何编写在中断中运行的代码比学习如何编写多线程代码更困难。中断会以线程不会对库函数造成严重破坏,并且由于信号处理程序中的细微错误而导致众所周知的程序中存在许多安全漏洞和漏洞。

答案 1 :(得分:0)

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

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

并传递AlarmFunctionObject :: func而不是myMemberFunc