2009-12-19 72 views
8

我正在写一个网络浏览器插件(NPAPI)JavaScript事件生成异步从浏览器插件(NPAPI)

我的插件启动一个工作线程,并作为工人的进展,我想传回的事件到Javascript。但是由于NPAPI线程模型,工作线程直接调用回NPAPI是不合法的,因此工作线程无法调用Javascript。

对此的一个解决方案是NPN_PluginThreadAsyncCall函数。但这是一个相对较新的功能。例如,它仅支持Firefox 3。

有什么办法可以从NPAPI插件获取异步事件传递/ JavaScript执行而不使用NPN_PluginThreadAsyncCall?人们在添加此功能之前做了什么?

回答

5

答案是肯定的...没有...

如果您需要支持旧的浏览器(Firefox的前3),您可以实现NPN_PluginThreadAsyncCall功能都自己。在Windows上,你可以通过创建一个可以容纳函数指针和void * opaque指针的数据结构来实现,然后用一个指向数据结构的指针作为LPARAM将自定义消息发布到主窗口。

主窗口WINPPROC在UI线程上运行,这是可以与Javascript交谈的线程。因此,当您在WINPROC中获得该消息时,只需将LPARAM转回指针,使用不透明数据调用该方法,然后释放该数据结构。

在Mac上,您可以用一个队列来存储事件,然后在NULL事件(Mac操作系统发送有关每个打勾)中检查是否有任何内容。如果是的话,弹出它,调用方法,释放它,然后继续。

在linux上可能还有一种方法可以做到这一点,但我不知道它是什么。

您可以在firebreath project中找到windows版本的示例。

Winproc传消息的处理是在本文件: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

事件和数据结构在它的头文件中定义: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

,点燃该事件的方法是在这里:

void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData) 
{ 
    if (m_hWnd != NULL) 
     ::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL, 
      (LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData)); 
} 
+1

谢谢!知道平台GUI事件循环线程对于NPAPI调用是安全的是非常有用的。我一定会检查Firebreath。 在Mac上,FWIW,如果你可以依靠Cocoa,在GUI线程上运行代码的简单方法是NSObject方法performSelectorOnMainThread。 – Geoff 2009-12-23 09:59:12

+0

是的,我想有人告诉我有关performSelectorOnMainThread的问题,但到目前为止我还没有必要使用它。目前仍然使用Firefox 2的用户比例非常小,所以我决定不再支持它。借助FireBreath,如果有人需要它足够严格(或者他们可以),我们可以添加支持,但我不需要它来支持我的任何东西。 =]有几个非常好的功能,直到firefox 2才实现;例如,NPN_Enumerate和NPN_Construct。此外,firefox 2有一个已知的bug,它无法看到在Windows中HKCU注册的插件,所以你必须是管理员。 – taxilian 2009-12-24 17:53:14