• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 8, comments - 12, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            編寫firefox plugin的跨平臺代碼

            Posted on 2009-05-18 15:59 eyesmart 閱讀(5784) 評論(2)  編輯 收藏 引用 所屬分類: Basic Knowledge

             

                  最近開發了一個firefox plugin,有點心得,決定將其寫下來。因為plugin的一些規則比較死板,所以了解其中函數的關系和調用的先后順序還要參考https://developer.mozilla.org/en/Plugins,本文主要討論Windows,Linux,MAC OS X三個平臺間的差異以及安裝更新的過程。

                  plugin其實是一個可執行的文件(動態庫),主要用于擴充瀏覽器對數據的解釋能力,如flash,pdf格式,也可以用于與本機其他模塊或對象進行通信,如具有腳本訪問功能的plugin。因為我想開發一個具有腳本訪問功能的plugin,所以從firefox源代碼包中我選擇了npruntime,因為這些結構都是比較固定的。

                  構建npruntime之前要安裝SDK,新建工程或makefile,設置一些宏定義,如XP_WIN=1,這個是很容易成功的。要是npruntime跨平臺還需要修改其代碼,經多次摸索以及google,我提煉出完整的接口如下:

             

            #include "npapi.h"

            #include 
            "npupp.h"

             

            char* NPP_GetMIMEDescription();

            #ifdef XP_MACOSX

            extern "C" {
             NP_EXPORT(NPError) OSCALL NP_Initialize(NPNetscapeFuncs
            * pFuncs
            #ifdef XP_UNIX
                       , NPPluginFuncs
            * pluginFuncs
            #endif  // XP_UNIX
                       );
             NP_EXPORT(NPError) OSCALL NP_GetEntryPoints(NPPluginFuncs
            * pFuncs);
             NP_EXPORT(NPError) OSCALL NP_Shutdown(
            void);
             NP_EXPORT(
            int) main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs,
                  NPP_ShutdownUPP
            * unloadUpp);
            }


            #endif  // XP_MACOSX

            #ifndef HIBYTE
            #define HIBYTE(x) ((((uint32_t)(x)) & 0xff00) >> 8)
            #endif

            NPNetscapeFuncs NPNFuncs;

            #if defined(XP_WIN) || defined(XP_MACOSX)

            NPError OSCALL NP_GetEntryPoints(NPPluginFuncs
            * pFuncs)
            {
             printf(
            "GetEntryPoints\n");
             
            if (pFuncs == NULL)
              
            return NPERR_INVALID_FUNCTABLE_ERROR;
             
            #ifdef XP_MACOSX
             
            // Webkit under OS X passes 0 in pFuncs->size, and Apple's sample code
             
            // (NetscapeMoviePlugIn) treats this as an output parameter.
             if (pFuncs->size == 0)
              pFuncs
            ->size = sizeof(NPPluginFuncs);
            #endif  // XP_MACOSX
             
             
            if (pFuncs->size < sizeof(NPPluginFuncs))
              
            return NPERR_INVALID_FUNCTABLE_ERROR;
             
             pFuncs
            ->version       = (NP_VERSION_MAJOR << 8| NP_VERSION_MINOR;
             pFuncs
            ->newp          = NPP_New;
             pFuncs
            ->destroy       = NPP_Destroy;
             pFuncs
            ->setwindow     = NPP_SetWindow;
             pFuncs
            ->newstream     = NPP_NewStream;
             pFuncs
            ->destroystream = NPP_DestroyStream;
             pFuncs
            ->asfile        = NPP_StreamAsFile;
             pFuncs
            ->writeready    = NPP_WriteReady;
             pFuncs
            ->write         = NPP_Write;
             pFuncs
            ->print         = NPP_Print;
             pFuncs
            ->event         = NPP_HandleEvent;
             pFuncs
            ->urlnotify     = NPP_URLNotify;
             pFuncs
            ->getvalue      = NPP_GetValue;
             pFuncs
            ->setvalue      = NPP_SetValue;
             pFuncs
            ->javaClass     = NULL;
             
             
            return NPERR_NO_ERROR;
            }


            #endif  // defined(XP_WIN) || defined(XP_MACOSX)

            char*
            NP_GetMIMEDescription()
            {
             printf(
            "GetMIMEDescription\n");
             
            return NPP_GetMIMEDescription();
            }


            NPError
            NP_GetValue(
            void* future, NPPVariable variable, void *value)
            {
             
            return NPP_GetValue((NPP_t *)future, variable, value);
            }


            // Under OS X, we rely on NP_GetEntryPoints() to be called to set up
            // the NPPluginFuncs structure, and we do not use the second parameter
            // `pluginFuncs` here for the compatibility with Safari under OS X.
            NPError OSCALL
            NP_Initialize(NPNetscapeFuncs
            * pFuncs
            #ifdef XP_UNIX
                          , NPPluginFuncs
            * pluginFuncs
            #endif  // XP_UNIX
                          )
            {
             printf(
            "Initialize\n");
             
            if(pFuncs == NULL)
              
            return NPERR_INVALID_FUNCTABLE_ERROR;
             
             
            if(HIBYTE(pFuncs->version) > NP_VERSION_MAJOR)
              
            return NPERR_INCOMPATIBLE_VERSION_ERROR;
             
             NPNFuncs.size                    
            = pFuncs->size;
             NPNFuncs.version                 
            = pFuncs->version;
             NPNFuncs.geturlnotify            
            = pFuncs->geturlnotify;
             NPNFuncs.geturl                  
            = pFuncs->geturl;
             NPNFuncs.posturlnotify           
            = pFuncs->posturlnotify;
             NPNFuncs.posturl                 
            = pFuncs->posturl;
             NPNFuncs.requestread             
            = pFuncs->requestread;
             NPNFuncs.newstream               
            = pFuncs->newstream;
             NPNFuncs.write                   
            = pFuncs->write;
             NPNFuncs.destroystream           
            = pFuncs->destroystream;
             NPNFuncs.status                  
            = pFuncs->status;
             NPNFuncs.uagent                  
            = pFuncs->uagent;
             NPNFuncs.memalloc                
            = pFuncs->memalloc;
             NPNFuncs.memfree                 
            = pFuncs->memfree;
             NPNFuncs.memflush                
            = pFuncs->memflush;
             NPNFuncs.reloadplugins           
            = pFuncs->reloadplugins;
             NPNFuncs.getJavaEnv              
            = pFuncs->getJavaEnv;
             NPNFuncs.getJavaPeer             
            = pFuncs->getJavaPeer;
             NPNFuncs.getvalue                
            = pFuncs->getvalue;
             NPNFuncs.setvalue                
            = pFuncs->setvalue;
             NPNFuncs.invalidaterect          
            = pFuncs->invalidaterect;
             NPNFuncs.invalidateregion        
            = pFuncs->invalidateregion;
             NPNFuncs.forceredraw             
            = pFuncs->forceredraw;
             NPNFuncs.getstringidentifier     
            = pFuncs->getstringidentifier;
             NPNFuncs.getstringidentifiers    
            = pFuncs->getstringidentifiers;
             NPNFuncs.getintidentifier        
            = pFuncs->getintidentifier;
             NPNFuncs.identifierisstring      
            = pFuncs->identifierisstring;
             NPNFuncs.utf8fromidentifier      
            = pFuncs->utf8fromidentifier;
             NPNFuncs.intfromidentifier       
            = pFuncs->intfromidentifier;
             NPNFuncs.createobject            
            = pFuncs->createobject;
             NPNFuncs.retainobject            
            = pFuncs->retainobject;
             NPNFuncs.releaseobject           
            = pFuncs->releaseobject;
             NPNFuncs.invoke                  
            = pFuncs->invoke;
             NPNFuncs.invokeDefault           
            = pFuncs->invokeDefault;
             NPNFuncs.evaluate                
            = pFuncs->evaluate;
             NPNFuncs.getproperty             
            = pFuncs->getproperty;
             NPNFuncs.setproperty             
            = pFuncs->setproperty;
             NPNFuncs.removeproperty          
            = pFuncs->removeproperty;
             NPNFuncs.hasproperty             
            = pFuncs->hasproperty;
             NPNFuncs.hasmethod               
            = pFuncs->hasmethod;
             NPNFuncs.releasevariantvalue     
            = pFuncs->releasevariantvalue;
             NPNFuncs.setexception            
            = pFuncs->setexception;
             
            // NPNFuncs.pluginthreadasynccall   = pFuncs->pluginthreadasynccall;
             
            #if defined(XP_UNIX) && !defined(XP_MACOSX)
             
            /*
              * Set up the plugin function table that Netscape will use to
              * call us.  Netscape needs to know about our version and size
              * and have a UniversalProcPointer for every function we
              * implement.
              
            */

             pluginFuncs
            ->version    = (NP_VERSION_MAJOR << 8+ NP_VERSION_MINOR;
             pluginFuncs
            ->size       = sizeof(NPPluginFuncs);
             pluginFuncs
            ->newp       = NewNPP_NewProc(NPP_New);
             pluginFuncs
            ->destroy    = NewNPP_DestroyProc(NPP_Destroy);
             pluginFuncs
            ->setwindow  = NewNPP_SetWindowProc(NPP_SetWindow);
             pluginFuncs
            ->newstream  = NewNPP_NewStreamProc(NPP_NewStream);
             pluginFuncs
            ->destroystream = NewNPP_DestroyStreamProc(NPP_DestroyStream);
             pluginFuncs
            ->asfile     = NewNPP_StreamAsFileProc(NPP_StreamAsFile);
             pluginFuncs
            ->writeready = NewNPP_WriteReadyProc(NPP_WriteReady);
             pluginFuncs
            ->write      = NewNPP_WriteProc(NPP_Write);
             pluginFuncs
            ->print      = NewNPP_PrintProc(NPP_Print);
             pluginFuncs
            ->urlnotify  = NewNPP_URLNotifyProc(NPP_URLNotify);
             pluginFuncs
            ->event      = NewNPP_HandleEventProc(NPP_HandleEvent);
             pluginFuncs
            ->getvalue   = NewNPP_GetValueProc(NPP_GetValue);
            #ifdef OJI
             pluginFuncs
            ->javaClass  = NPP_GetJavaClass();
            #endif  // OJI
            #endif  // defined(XP_UNIX) && !defined(XP_MACOSX)
             
             
            return NPP_Initialize();
            }


            NPError OSCALL NP_Shutdown()
            {
             NPP_Shutdown();
             
            return NPERR_NO_ERROR;
            }


            #ifdef XP_MACOSX

            int main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp)
            {
             NPError err 
            = NPERR_NO_ERROR;
             printf(
            "main\n");
             
            //
             
            // Ensure that everything Netscape passed us is valid!
             
            //
             if ((nsTable == NULL) || (pluginFuncs == NULL) || (unloadUpp == NULL))
              err 
            = NPERR_INVALID_FUNCTABLE_ERROR;
             
             
            //
             
            // Check the "major" version passed in Netscape's function table.
             
            // We won't load if the major version is newer than what we expect.
             
            // Also check that the function tables passed in are big enough for
             
            // all the functions we need (they could be bigger, if Netscape added
             
            // new APIs, but that's OK with us -- we'll just ignore them).
             
            //
             if (err == NPERR_NO_ERROR)
             
            {
              
            if (HIBYTE(nsTable->version) > NP_VERSION_MAJOR)
               err 
            = NPERR_INCOMPATIBLE_VERSION_ERROR;
             }

             
             
            if (err == NPERR_NO_ERROR)
             
            {
              err 
            = NP_Initialize(nsTable, NULL);
             }

             
             
            if (err == NPERR_NO_ERROR)
             
            {
              err 
            = NP_GetEntryPoints(pluginFuncs);
              
            *unloadUpp = NewNPP_ShutdownProc(NP_Shutdown);
             }

             
             
            return err;
            }


            #endif  // XP_MACOSX


            這三個平臺接口實現的功能都一樣,但firefox硬把他們寫的這么復雜。仔細對比一下npruntime原來的接口就會明白這三個平臺到底有什么不同,這里多出了一個main函數,這個main函數是在MAC OS X的firefox 2里面才有的,在firefox 3中已經取消了,但為了插件的可移植性還是把這個函數加了進來,里面調用了了其他的三個接口函數來實現,本質上沒有任何區別。
                  這3個平臺的聲明plugin信息的方式也是不一樣的。Windows的plugin信息都存放在資源的Version中,可以用VC或記事本打開進行編輯,Linux上的MIMEType需要通過導出函數NP_GetMIMEDescription來獲取,而其他的信息則通過NPP_GetValue來獲取,firefox通過這個函數向plugin請求插件名稱和插件描述。在MAC OS X上plugin信息是放在資源腳本里,要先定義.r 文件,添加到XCode中,.r文件的一個范例如下
            #include <CoreServices/CoreServices.r>
            resource 'STR#' (127)
            {{
             "myplugins"
            }};

            resource 'STR#' (128)
            {{
             "application/myscriptable-plugin",
             "*"
            }};

            resource 'STR#' (126)
            {{
             "<a href=\"http://www.mypage.com\">MyPlugin 1.0.0</a> "
             "can do something",
             "my discription。"
            }};
            然后將這個文件和源文件一起編譯成一個Bundle(相當于一個DLL),在XCode中還需要將CFBundlePackageType改為BRPL。因為MAC OS X還可運行在ppc架構上,所以最好能編寫成universal版,這樣就不用考慮平臺問題了。
            至此,這個接口就算完成了,能夠在三個平臺上工作。

             

            Feedback

            # re: 編寫firefox plugin的跨平臺代碼  回復  更多評論   

            2009-05-19 11:55 by abettor
            好文章,學習了~~

            # re: 編寫firefox plugin的跨平臺代碼  回復  更多評論   

            2010-03-28 22:34 by lwl
            @abettor
            我正在找這方面的內容,急需求,能幫幫我?QQ:657501127 EMail:lwlwork@sina.com
            性做久久久久久免费观看| 久久久无码精品亚洲日韩蜜臀浪潮| 精品国产乱码久久久久软件| 久久久噜噜噜久久中文字幕色伊伊| 亚洲一区精品伊人久久伊人| 色妞色综合久久夜夜| 亚洲国产精品久久久久婷婷软件| 亚洲国产成人久久综合一区77| 亚洲人成精品久久久久| 久久本道伊人久久| 国内精品久久久久影院亚洲| 国产91久久精品一区二区| 欧美亚洲国产精品久久久久| 99久久99久久久精品齐齐| 久久一本综合| 精品水蜜桃久久久久久久| 无码伊人66久久大杳蕉网站谷歌| 免费观看成人久久网免费观看| 欧美精品乱码99久久蜜桃| 久久青青草原国产精品免费| 久久精品国产亚洲77777| 久久久久久国产精品无码下载| 国产99久久久久久免费看| 久久国产色AV免费看| 久久精品综合网| 亚洲精品NV久久久久久久久久| 国产一级持黄大片99久久| 久久免费看黄a级毛片| 久久精品国产亚洲av瑜伽| 婷婷综合久久狠狠色99h| 国产精品一久久香蕉国产线看观看| 久久综合偷偷噜噜噜色| 色悠久久久久久久综合网| 久久久久久国产精品美女| 99久久久久| 狠狠人妻久久久久久综合蜜桃| 日本久久久久久中文字幕| 91久久香蕉国产熟女线看| 久久久久综合中文字幕| 午夜精品久久久久9999高清| 久久精品国产一区二区|