【问题标题】:binding argument to ansi c callback将参数绑定到 ansi c 回调
【发布时间】:2015-10-14 06:59:11
【问题描述】:

我在接受回调的 lib 中有函数,比如说 foo:

typedef void (*CallbackType)(unsigned int); 
void foo(const tchar* path, CallBackType); // library function

static void boo(unsigned int percent)
{
static ProgressBarClass progressBar;
 progressBar.setProgressValue(percent);
}

但我不能让对象 progressBar 是静态的,所以我想我会绑定对它的引用:

static void boo(unsigned int percent, ProgressBarClass& progressBar)
{
    progressBar.setProgressValue(percent);
}

void something() {
    ProgressBarClass progressBar;
    tr1::function<static void(unsigned int)> f = tr1::bind(boo, tr1::placeholders::_1, tr1::ref(progressBar));
    foo(someWCHARPath, f);
}

但我当然不能将 tr1::function 转换为 ansi c 回调,所以问题是有什么好的和干净的我能做什么?我可以将 progressBar 绑定到 ansic 回调吗?

【问题讨论】:

  • 您的参考“解决方案”将被破坏,因为progressBar 的生命周期在something 返回时结束。
  • foo 使用回调填充进度条,因此不会被破坏。
  • 我认为foo 是异步的。脑部故障,抱歉。
  • “ansi c 回调”到底是什么意思?一个可以通过函数指针调用的普通函数?
  • @Lundin, typedef void (*CallbackType)(unsigned int) 对我来说意味着 ansi c 回调:)

标签: c++ tr1


【解决方案1】:

您必须使用具有该签名的全局函数。既然给了你函数指针类型typedef void (*CallbackType)(unsigned int),你的回调需要返回void并带一个unsigned int参数:

void function(unsigned int);
CallbackType funcPtr = &function;

如果回调没有提供“用户数据”参数(通常是void*)来传递额外的数据,您要么必须以某种方式将它们与现有参数相匹配(也许可以使用整数的某些位),或者使用全局变量,除非绝对必要,否则我不建议这样做。

【讨论】:

  • 你能给我举个例子,你是如何想象“求助于全局函数”的吗?
  • @user1326505 我相应地编辑了我的答案。基本上,在 C 中,您无法选择使用 C++11 函数提供的任何不错的特性(例如绑定、lambda)。
  • 好吧 boo 函数是全局函数,但它必须以某种方式获得对 ProgressBarClass 对象类的相同引用,所以我可以使用 boo 函数,例如 100 次。也许没有好的解决方案......
  • 是的,恐怕在这种情况下没有干净的解决方案(只有全局变量,它只允许同时执行一个回调并引入许多其他问题)。这就是深思熟虑的 C 回调 API 提供额外的 void* 参数的原因。
【解决方案2】:

如果ProgressBarClass 类型的任何对象都可以,只需删除static 关键字即可。

如果您需要ProgressBarClass 类型的特定对象,那么不,没有办法通过您拥有的 C 回调传递一个对象。您必须有 某种 静态变量,它允许您获取对象。它不一定是ProgressBarClass。也许您应该有一个代表您的应用程序的单例,以及返回其各种 GUI 元素的方法。

【讨论】:

  • 不是任何对象都是好的,因为它是进度条类,所以我需要“记住”我已经填写了进度,例如50%。
猜你喜欢
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多