代码之家  ›  专栏  ›  技术社区  ›  Alexander Rafferty

将方法类化为winAPI回调

  •  3
  • Alexander Rafferty  · 技术社区  · 14 年前

    将winAPI消息回调函数设置为类的方法是否可行。如果是这样,如何最好地实施这一点?我想知道这是否可能。

    提前感谢:)。

    4 回复  |  直到 14 年前
        1
  •  7
  •   sbi    14 年前

    不能使用非- static C回调的成员函数。

    但是,通常C回调有一个路由到回调的用户数据指针。这可以通过一个 静止的 成员功能:

    // Beware, brain-compiled code ahead!
    
    typedef void (*callback)(int blah, void* user_data);
    
    void some_func(callback cb, void* user_data);
    
    class my_class {
    public:
      // ...
      void call_some_func()
      {
         some_func(&callback_,this);
      }
    private:
      void callback(int blah)
      {
        std::cout << blah << '\n';
      }
      static void callback_(int blah, void* user_data)
      {
        my_class* that = static_cast<my_class*>(user_data);
        that->callback(blah);
      }
    };
    
        2
  •  2
  •   Abyx    14 年前

    如果您使用MSVC,并且目标是x86-32(而不是x86-64),则可以对成员函数使用\uu stdcall约定。(cdecl也起作用)

    带\u stdcall 将作为第一个参数传递,因此可以编写

    typedef void(__stdcall *callback_t)(void* arg);
    void set_callback(callback_t callback, void* callbackParameter);
    
    struct Foo
    {
       int x;
       void __stdcall someCallback() { this->x = 1; }
    };
    

    但是

    Foo foo;
    set_callback((callback_t)&Foo::someCallback, this);
    

    不起作用:不能直接将成员函数指针强制转换为标准的指针。您应该使用一种变通方法来实现这一点:

    static_assert(sizeof(&Foo::someCallback) == sizeof(void*), "");
    // or assert()
    

    如果存在多重继承,并且someCallback是虚拟的,那么这个断言可能会失败。 要禁止多重继承,请使用\uu single \u inheritation关键字:

    struct __single_inheritance Foo { /* ....*/ };
    

    其次,应该使用

    union
    {
        void(__stdcall Foo::*src)();
        callback_t dst;    
    } u = {&Foo::someCallback};
    set_callback(u.dst, this);
    

    void(__stdcall Foo::*temp)() = &Foo::someCallback;
    set_callback(*(callback_t*)&temp, this);
    

    只有你能通过,它才有效 作为第一个参数回调。

    B9 XX XX XX XX mov ecx, <this>
    68 XX XX XX XX push <function member address>
    C3 ret
    

    它将是回调存根,它将\uu stdcall转换为\uu thiscall。

        3
  •  1
  •   Franci Penov    14 年前

    this win32api不能给他们的。

        4
  •  0
  •   Chubsdad    14 年前