C ++对象函数指向函数

时间:2011-08-14 07:51:47

标签: c++ callback member-function-pointers

我在C ++应用程序中使用了一个C库。该库具有以下签名的功能:

void awe_webview_set_callback_js_callback(awe_webview* webview, void (*callback)(awe_webview* caller, const awe_string* object_name, const awe_string* callback_name, const awe_jsarray* arguments));

我正在尝试将函数设置为回调函数,我希望能够使用以下类成员函数

void BattleScreen::HandleWebViewCallbacks(awe_webview* WebView, const awe_string* object, const awe_string* callback, const awe_jsarray* arguments)
{
    //handling code
}

我无法直接绑定它并基于此http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.2我有一个可能的解决方案,我将创建一个静态成员来处理回调(因为基于该网站,它应该没问题)并添加静态成员要调用的此类的静态实例。

即。将以下内容添加到BattleScreen:

static BattleScreen* callbacktarget;
static BattleScreen::TopLevelHandleWebViewCallbacks(awe_webview* WebView, const awe_string* object, const awe_string* callback, const awe_jsarray* arguments)
{
      callbacktarget->HandleWebviewCallbacks(WebView, object, callback, arguments);
}

将它绑定在构造函数中,如下所示:

awe_webview_set_callback_js_callback(this->GetWebView(), static_cast<void (*)(awe_webview*, const awe_string*, const awe_string*, const awe_jsarray*)>(&BattleScreen::TopLevelHandleWebViewCallbacks));

并将对象分配给构造函数中的callbacktarget。

BattleScreen::callbacktarget = this;

问题是我无法知道在任何时候我将拥有多少这些类(它将是最小的,但可能大于1)。我考虑使callbacktarget成为BattleScreen *的矢量,我可以在TopLevelHandleWebViewCallbacks内部进行迭代并进行比较,如下所示:

if (callbacktargets[index]->GetWebview() == WebView)
{
     callbacktargets[index]->HandleWebviewCallbacks(WebView, object, callback, arguments);
}

但问题在于我只是在比较awe_webview指针,这似乎是一个非常糟糕的主意。该库是闭源的,awe_webview是C构造,所以我看不出是什么构成它们,以及是否有任何属性可以进行更合适的比较。有一个很好的解决方案吗?

如果我不清楚或您需要其他信息,请告诉我。

提前致谢

2 个答案:

答案 0 :(得分:2)

三解:

  1. 验证库是否允许您将任意“上下文”指针绑定到每个awe_webview。他们通常这样做。如果是,则存储指向BattleScreen的指针,并在调用静态回调时,从this的'context'中检索webview指针,并在此指针上调用成员函数。 / p>

  2. 使用全局map<awe_webview*, BattleScreen*>。在静态回调中,找到与BattleScreen对应的webview。需要锁定全局地图,而不是漂亮。

    注意:使用指向webview的指针作为唯一ID几乎可以肯定。它始终是独一无二的。

  3. 使用thunk(例如http://www.codeproject.com/KB/cpp/thunk32.aspx)。

答案 1 :(得分:2)

回调接收awe_webview指针的事实或多或少证明了比较它们是他们期望你做的。

但是,我会修改您的解决方案,以便在Web视图与BattleScreens之间使用全局地图:

static std::map<awe_webview*, BattleScreen*> gWebViewBattleScreen;

然后有一个全局回调从中拾取BattleScreen对象并调用其方法:

static void webviewCallback(awe_webview* caller, ......)
{
    if (gWebViewBattleScreen.find(caller) != gWebViewBattleScreen.end())
        gWebViewBattleScreen[caller]->HandleWebViewCallbacks(......)
}

漂亮的库允许您使用回调传递上下文指针,因此您可以为您设置的每个回调分配类似BattleObject *的内容:

void set_nice_callback(void (*callback)(Params params, void* context), void* context);

您正在使用的库似乎不太好:)您可能希望将其开发人员指向此。