【问题标题】:How do I call a C-function with a Functor that expects a pointer to a void function in C++?如何使用需要指向 C++ 中的 void 函数的指针的 Functor 调用 C 函数?
【发布时间】:2012-06-21 00:46:43
【问题描述】:

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

【问题讨论】:

  • 您不能将非静态成员函数作为 c 样式函数传递。尝试将函数设为静态。
  • @cppguy:就是这样,我不能。它是用户传入的 FunctorObject。我无法控制它。
  • std::bind (c++11) 或 boost::bind (
  • @nijansen:我正在使用 VS2010。将在 2011 年结束 Beta 版并发布其第一个 Service Pack。
  • 所以std::bind 不是选项,但是boost::bind 呢?

标签: c++ c function-pointers allegro


【解决方案1】:

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

void (*)(void);

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

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

然而,

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

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

中断上下文是危险的,它与线程相同,您应该将 C++ 代码置于中断中除非你非常擅长弄清楚你的 C++ 代码是做什么的。

不要将 C++ 函数传递给 install_int_ex(同样,除非您确切地知道您的 C++ 代码正在或未生成的库是什么。) p>

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

【讨论】:

  • 如果我能投票一百万次,我会的。我希望你能接受一票和接受。 :)
【解决方案2】:

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

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

并传递 AlarmFunctionObject::func 而不是 myMemberFunc

【讨论】:

  • 我无法控制传入的 Functor 对象。
猜你喜欢
  • 2018-04-19
  • 2017-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2013-01-26
  • 2014-09-24
相关资源
最近更新 更多