我在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构造,所以我看不出是什么构成它们,以及是否有任何属性可以进行更合适的比较。有一个很好的解决方案吗?
如果我不清楚或您需要其他信息,请告诉我。
提前致谢
答案 0 :(得分:2)
三解:
验证库是否允许您将任意“上下文”指针绑定到每个awe_webview
。他们通常这样做。如果是,则存储指向BattleScreen
的指针,并在调用静态回调时,从this
的'context'中检索webview
指针,并在此指针上调用成员函数。 / p>
使用全局map<awe_webview*, BattleScreen*>
。在静态回调中,找到与BattleScreen
对应的webview
。需要锁定全局地图,而不是漂亮。
注意:使用指向webview的指针作为唯一ID几乎可以肯定。它始终是独一无二的。
使用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);
您正在使用的库似乎不太好:)您可能希望将其开发人员指向此。