c++ - 为 C 回调包装器使用可变参数模板
问题描述
我目前正在尝试包装一个 C 库(将其 GTK 命名为培训)。我想看看我是否可以为回调使用可变参数模板,因为它们在信号的回调中具有不同的参数计数。我打算使用std::function
可变参数模板。有点像这样:
template<typename... args> class callback_t { public:
struct cb_data_t
{
std::function<void (args...)> callback;
};
// data contains cb_data
static void callback_from_a_c_function(args... a, void *data)
{
cb_data_t *cbd = (cb_data *)data;
cbd.callback(a...);
}
private:
cb_data_t cb_data;
};
我对此很陌生,但这甚至可以将可变参数传递给 astd:function
吗?
解决方案
但这甚至可以将可变参数传递给 std:function 吗?
我不明白你想要获得什么,但是......鉴于它们args...
被固定为类的模板参数,是的:你可以。
在您的静态方法中进行了一些更正:(1)您必须强制data
转换为cb_data_t
指针( no cb_data
)和(2)您必须考虑cbd
作为指针的计数,因此您必须callback()
通过箭头运算符调用,而不是通过点算子
static void callback_from_a_c_function(args... a, void *data)
{ // ......................VV
cb_data_t *cbd = (cb_data_t *)data;
cbd->callback(a...);
} // ^^
或者,也许更好,您可以直接将最后一个参数作为cb_data_t
指针传递
static void callback_from_a_c_function(args... a, cb_data_t * cbd)
{ cbd->callback(a...); }
请注意,接收cd_data_t
指针作为参数,您没有使用该cb_data
成员。
以下是完整的编译和简化示例
#include <iostream>
#include <functional>
template <typename ... args>
struct callback_t
{
struct cb_data_t
{ std::function<void (args...)> callback; };
static void callback_from_a_c_function(args... a, cb_data_t * cbd)
{ cbd->callback(a...); }
};
extern "C"
{
void foo (int, long)
{ std::cout << "foo!" << std::endl; }
}
int main ()
{
callback_t<int, long>::cb_data_t cbd{&foo};
callback_t<int, long>::callback_from_a_c_function(0, 1l, &cbd);
}
但在我看来,这个解决方案过于复杂。不幸的是,我不明白你想如何使用你的包装器,所以我不能建议你更简单的东西。
推荐阅读
- google-apps-script - 无法获取 getColumn 和 getRow 方法以返回任何值
- azure - 使用 cloud-Init 在 Azure 上安装 docker 和 docker-compose
- excel - 从具有是/否字段的多列表中透视表
- c++ - 预处理器宏可以扩展一些粘贴的参数吗?
- amazon-s3 - 我如何在 Redhat AWS linux 机器上安装 apt-get
- sql-server - SSIS DtsDebugHost.exe 内存溢出
- reactjs - Fontawesome 在我的反应应用程序中不起作用
- python - 借助 AWS SageMaker,是否可以使用 sagemaker 开发工具包部署预训练模型?
- javascript - 如何在 Node.js 中读取 Windows 快捷方式链接到的位置?
- xamarin - Xamarin.Forms:向网格中的标签添加填充?