使常规函数使用模板包装成员函数
Making a regular function wrap a member function with templates
我正在使用一个框架,该框架具有C API,其typedef如下所示:
typedef int (*function_type)(int argc, voidptr_t args[], void *data)
以及一个采用此类函数指针的函数,如下所示:
void create_callback(function_type fn, void *data);
(如果不是很明显,voidptr_t
只是 void 的另一个 typedef *)
框架将根据需要在特定时间调用回调,并设置 argc 和 args 参数以反映当时有效的条件。 argc 永远不会小于 1,并且 args 中的第一个条目将始终是指向某些有效数据的指针,这些数据可以强制转换为指向程序中某个类的指针,并且在许多方面可以被认为是"this"指针,因为它指示回调应对其操作或使用的对象或数据。
我将从C++调用此 API,并且想要一种方法来包装如下所示的类的成员函数:
class A
{
int member_fn1(int argc, voidptr_t args[], void *data);
};
class B
{
int member_fn2(int argc, voidptr_t args[], void *data);
};
现在我想要一种将这些成员函数用作回调的方法......我可以通过更改 A 和 B 的定义来包含可以用作回调的静态函数来做到这一点,如下所示:
class A
{
int member_fn1(int argc, voidptr_t args[], void *data);
static int call_fn1(int argc, voidptr_t args[], void *data)
{
((A*)args[0])->*fn1(argc-1,&args[1],dat
}
};
class B
{
int member_fn2(int argc, voidptr_t args[], void *data);
static int call_fn2(int argc, voidptr_t args[], void *data)
{
((B*)args[0])->fn2(argc-1,&args[1],data);
}
};
但是,如果我必须为我想用作回调的每个成员函数定义一个这样的静态函数,这将变得非常乏味。 但是,从中可以看出,这个想法是仅将其他参数传递到成员函数中,并允许第一个参数假定this
的值。
我想做的是定义某种模板函数,我可以将其作为参数传递给create_callback
,并将包装一个成员函数,以便可以将其作为回调调用。
wrap_function看起来像这样:
template<????> int wrap_function(int argc, voidptr_t args[], void *data)
{
try {
return ((X*)args[0])->fn(argc-1, &args[1], data);
} catch(...) {
// handle any exception safely, because we can't let it get back into C code
handle_exception(std::current_exception());
return -1
}
}
其中X
是类的类型名,fn
是成员函数本身。
请注意,此函数还可以灵活地处理异常,否则我将为我想用作回调的每个成员函数一遍又一遍地编写几乎相同的代码......这就是为什么我想将其设置为模板函数。
因此,一旦我定义了wrap_function
,我就可以通过以下方式在 API 中定义回调:
create_callback(wrap_function<&A::member_function1>, some_data)
create_callback(wrap_function<&B::member_function2>, some_other_data)
由于wrap_function
的定义只是一个常规函数而不是一个方法,我可以将其地址作为常规函数指针传递给 C API,并且函数的职责是将其工作委托给正确类中的正确成员函数。
但是,我如何准确定义wrap_function
模板以使其正常工作?
我真诚地希望这个问题是清楚的...如果有人觉得需要更好地描述,请在评论中具体指出下面不清楚的地方,以便我改进这个问题。
template <typename X, int (X::*fn)(int, voidptr_t[], void*)>
int wrap_function(int argc, voidptr_t args[], void *data) {
return (static_cast<X*>(args[0])->*fn)(argc-1, &args[1], data);
}
我认为应该有效。您可以以这种方式使用它:
create_callback(wrap_function<A, &A::member_function1>, some_data)
- 将 N-arg 函数包装到另一个函数中
- 将函数包装器转换为 std::function
- C++函数包装器来捕获某些信号
- 考虑引用和常量的可变参数函数包装器
- 将此私有删除器函数包装在结构中的目的是什么?
- 处理模板函数包装中的void返回
- 如何使用可变模板编写通用函数包装器
- 其他成员函数的通用"成员函数"包装器?
- 为什么将函数包装到 lambda 中可能会使程序更快?
- 创建一个允许轻松创建虚拟函数包装器函数的C++宏
- 将 c++ 函数包装为 c#,具有结构的总动态大小
- 返回对 std::函数包装的 lambda 中静态变量的引用会导致段错误
- 标准库中是否有与 std::thread 的构造函数语义匹配的类型擦除函数包装器?
- 如何编写 C++ 类成员函数包装器
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 任何返回类型的可变参数函数包装器
- 具有临时函数包装器的完美转发
- 推导成员函数包装器的返回类型时出错
- 使用可变参数模板函数包装基于省略号的函数
- 将C 模板构造函数包装在模板类中