如何使用c++成员函数作为C框架的回调函数
How to use a C++ member function as the callback function for a C framework
有一个C库(我不能更改)支持类型为
的回调函数。void (*callback)(void *appContext, int eventid)
我想设置一个c++函数作为回调。
具体来说,我有以下问题?
我需要在
"extern C"
块下声明回调函数吗?成员函数必须是静态的才能成为回调函数吗?是否可以使用非静态成员函数?如果是,怎么做?什么时候推荐使用非静态成员函数?
函数是否是模板函数有关系吗?
非C类风格的函数比类成员函数有什么优势吗?
我正在一个旧的vc++编译器上尝试这些变体,它不支持最新的c++标准。但是代码需要与平台无关,并且应该在大多数c++编译器上工作。我想知道关于回调的推荐做法是什么?
是否需要在extern "C"下声明回调函数?
。extern "C"仅在直接从C调用c++函数而不使用函数指针时是必需的。如果使用函数指针,则不需要extern "C"。
可以使用非静态成员函数作为回调吗?
。类A的非静态成员函数有一个隐式的第一个形参,对应于这个指针。
可以使用静态成员函数作为回调吗?
YES,只要签名与回调的签名匹配。
函数是否是模板函数有关系吗?
不,模板函数可以用作回调函数,只要实例化模板的签名与回调函数匹配。
假设appContext
是传递给进行回调的函数的不透明指针,您可以像这样获得对特定对象的成员函数的回调:
class myclass {
void do_something() {
// call function making the callback using _event_handler
// as the callback function and the "this" pointer as appContext
}
// make sure the raw callback uses the correct calling convention (cdecl, stdcall, etc.)
static void _handle_event(void* appContext, int eventid) {
// forward the event to the actual object
static_cast<myclass *>(appContext)->handle_event(eventid);
}
void handle_event(int eventid) {
// do object-specific event handling
}
};
几个答案提到extern "C"
作为要求。这是完全错误的。extern "C"
仅在直接从c++调用C函数时是必需的。它用于告诉c++编译器"在为该函数生成符号名时不要应用名称混淆"。你正在传递一个c++函数指针给一个C函数。只要调用约定匹配,它就可以正常工作。不涉及函数名
如果你的成员函数是静态的,这应该可以工作。
这并不像在extern "C"
块下声明回调函数那么简单。您需要弄清楚C库对其函数使用的调用约定。
我要使用的术语是微软特有的,但同样的规则也应该适用于其他平台。
默认情况下,Visual c++编译器使C函数__stdcall
和c++函数__cdecl
。不能混用和匹配这些调用约定,因为每个调用约定对谁清理堆栈都有不同的假设。这里有一个更详细的解释。
一旦匹配了调用约定,最简单的方法是将c++回调函数声明为独立于命名空间作用域的函数;如果它需要是一个成员函数,那么是一个静态成员函数。在这两种情况下,您都应该能够使用std::bind
将指针绑定到类的实例。您甚至可以使用std::bind
来绑定非静态成员函数,但我想不起语法。
-
确保它在全局作用域中
-
使用
extern "C"
-
使用
__cdecl
,如果需要:void (_cdecl *callback)
严格来说,你不能。C回调必须指定为extern "C"
,这对于成员函数来说是不可能的。只能使用独立的函数。您可以从这里将调用转发给任何c++函数,包括静态或非静态成员函数。
根据不同的平台,你有时可以跳过extern "C"
,但我不会测试我的运气。
- "error: no matching function for call to"构造函数错误
- 延迟函数使打开的框架窗口冻结,直到指定的时间过去
- 在Google测试框架中,如何期望函数调用或其他功能调用
- 当两个函数位于一行中时,堆栈框架的样子
- 为什么我不能用这个函数在Qt框架中打开另一个进程?
- 编写一个功能,该函数将使用框架交换两个整数
- 如何在构造函数中使用QT Undo框架
- C ++使用框架崩溃,构造函数错误
- 开放框架:绘制函数被多次调用
- 分析框架中的函数
- 能够模拟非虚拟方法和C函数的C++模拟框架
- 理解C/ c++中函数调用的堆栈框架
- 在c++和Qt框架下使用InitiateSystemShutdown()函数
- 使用yii框架中的.cpp文件中的函数
- 构造函数是否有堆栈框架
- 如何使用c++成员函数作为C框架的回调函数
- 从lambda的内部框架修改via闭包中的变量安全吗?lambda是从一个不再存在的函数创建的
- 当C/C++中涉及两个进程时,如何使用伪函数框架
- 使用给定框架调用/引用另一个类C++变量或函数
- 是否可以使用GDB查看未命名的框架/函数参数