2009-12-19 63 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