0

我正在使用需要传入回调函数的 API,但它不支持任何用户定义的参数来传递对象指针。

从我的静态/外部“C”回调函数中恢复对象的选项是什么?

我正在使用SetAbortProc(),它需要一个 HDC 并传递给AbortProc()回调。不幸的是,我看不到任何将更多数据与 HDC 相关联的方法。

我能想到的解决方案:

  • 使用全局 Cls *my_abort_object
    应该可以工作,因为一次只能激活一个打印作业。这似乎有点草率,但也许这只是我?
  • 使用全局 std::map<HDC, Cls*>
    对我来说可能没用,因为只能激活一个打印作业。全局指针解决方案更简单,在这种情况下没有缺点。
  • 使用一个封装整个中止事物的单例
    可能是最明智的方法,无需太多工作。
  • 使用 ATL 风格的 thunk
    (这基本上是运行时生成的代码,它调用real_callback(HARDCODED_OBJ_PTR, cb_arg1, cb_arg2, ...);作为回调函数传入的代码)。
    会很好,但很难自己做,数据执行预防有问题等。框架可以做的事情,你不能轻易模仿。

我目前倾向于单例解决方案,因为它似乎是最干净的,没有太多开销。我会很感激任何建议!

额外信息:使用 MSVC Espress 2010 进行 C++ Win32 编程

4

3 回答 3

1

如果你想要一个稍微健壮的解决方案,我会继续使用一个命名空间级别的 API,它包装了一个单例的map- HDC>class*关系。如果您需要在多个 HDC 上下文中使用该功能,那么您最好不要去。我想公共 API 会非常相似,SetAbortProc()但它也会为每个 HDC 创建和映射相应的处理程序对象。

由于您只需要一个 HDC,因此紧随其后的是只使用一个全局指针(具有某种断言/常量,因此它不能变异)并依赖于在您获得中止回调时设置的指针。

于 2013-01-23T17:06:55.797 回答
0

这让我很惊讶,因为微软的 IME 非常擅长提供 userdata 参数。但是,如果做不到这一点,最佳解决方案是使用 LLVM。它们为您提供简单易用的 JIT thunk 功能。

于 2013-01-23T17:10:17.087 回答
-1

很遗憾看到带有回调的 API 不允许使用总是限制其他用户的用户数据。不过,我个人会倾向于使用单例类型。

不过,您可能应该将此情况报告给 API 的开发人员。您还可以发现,如果您可以在回调中从 API 访问对象,有时您可以将指针/数据插入到其架构的其他部分,在我看来,向开发人员寻求帮助是最好的选择。您甚至可以在帮助自己的同时帮助他们。

于 2013-01-23T16:57:21.790 回答