• <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++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

             

                  最近開發(fā)了一個(gè)firefox plugin,有點(diǎn)心得,決定將其寫下來。因?yàn)閜lugin的一些規(guī)則比較死板,所以了解其中函數(shù)的關(guān)系和調(diào)用的先后順序還要參考https://developer.mozilla.org/en/Plugins,本文主要討論Windows,Linux,MAC OS X三個(gè)平臺(tái)間的差異以及安裝更新的過程。

                  plugin其實(shí)是一個(gè)可執(zhí)行的文件(動(dòng)態(tài)庫),主要用于擴(kuò)充瀏覽器對(duì)數(shù)據(jù)的解釋能力,如flash,pdf格式,也可以用于與本機(jī)其他模塊或?qū)ο筮M(jìn)行通信,如具有腳本訪問功能的plugin。因?yàn)槲蚁腴_發(fā)一個(gè)具有腳本訪問功能的plugin,所以從firefox源代碼包中我選擇了npruntime,因?yàn)檫@些結(jié)構(gòu)都是比較固定的。

                  構(gòu)建npruntime之前要安裝SDK,新建工程或makefile,設(shè)置一些宏定義,如XP_WIN=1,這個(gè)是很容易成功的。要是npruntime跨平臺(tái)還需要修改其代碼,經(jīng)多次摸索以及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


            這三個(gè)平臺(tái)接口實(shí)現(xiàn)的功能都一樣,但firefox硬把他們寫的這么復(fù)雜。仔細(xì)對(duì)比一下npruntime原來的接口就會(huì)明白這三個(gè)平臺(tái)到底有什么不同,這里多出了一個(gè)main函數(shù),這個(gè)main函數(shù)是在MAC OS X的firefox 2里面才有的,在firefox 3中已經(jīng)取消了,但為了插件的可移植性還是把這個(gè)函數(shù)加了進(jìn)來,里面調(diào)用了了其他的三個(gè)接口函數(shù)來實(shí)現(xiàn),本質(zhì)上沒有任何區(qū)別。
                  這3個(gè)平臺(tái)的聲明plugin信息的方式也是不一樣的。Windows的plugin信息都存放在資源的Version中,可以用VC或記事本打開進(jìn)行編輯,Linux上的MIMEType需要通過導(dǎo)出函數(shù)NP_GetMIMEDescription來獲取,而其他的信息則通過NPP_GetValue來獲取,firefox通過這個(gè)函數(shù)向plugin請(qǐng)求插件名稱和插件描述。在MAC OS X上plugin信息是放在資源腳本里,要先定義.r 文件,添加到XCode中,.r文件的一個(gè)范例如下
            #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。"
            }};
            然后將這個(gè)文件和源文件一起編譯成一個(gè)Bundle(相當(dāng)于一個(gè)DLL),在XCode中還需要將CFBundlePackageType改為BRPL。因?yàn)镸AC OS X還可運(yùn)行在ppc架構(gòu)上,所以最好能編寫成universal版,這樣就不用考慮平臺(tái)問題了。
            至此,這個(gè)接口就算完成了,能夠在三個(gè)平臺(tái)上工作。

             

            Feedback

            # re: 編寫firefox plugin的跨平臺(tái)代碼  回復(fù)  更多評(píng)論   

            2009-05-19 11:55 by abettor
            好文章,學(xué)習(xí)了~~

            # re: 編寫firefox plugin的跨平臺(tái)代碼  回復(fù)  更多評(píng)論   

            2010-03-28 22:34 by lwl
            @abettor
            我正在找這方面的內(nèi)容,急需求,能幫幫我?QQ:657501127 EMail:lwlwork@sina.com
            亚洲伊人久久成综合人影院| 久久久久国产一区二区| 欧美精品福利视频一区二区三区久久久精品| 久久亚洲熟女cc98cm| 无码8090精品久久一区 | 国产一区二区三精品久久久无广告| 中文字幕乱码久久午夜| 久久久这里只有精品加勒比| 久久无码精品一区二区三区| 国产成人AV综合久久| 国産精品久久久久久久| 国产精品免费久久| 久久久噜噜噜久久| 热综合一本伊人久久精品| 欧美精品福利视频一区二区三区久久久精品| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 精品久久人人爽天天玩人人妻| 伊人情人综合成人久久网小说| 日韩一区二区三区视频久久| 国产精品久久久久久久app| 久久精品国产亚洲AV不卡| 亚洲欧美日韩中文久久| 狠狠色丁香久久婷婷综合五月 | a级毛片无码兔费真人久久| 国产精品熟女福利久久AV| 久久久久人妻一区精品| 久久人人爽人人人人爽AV| 久久精品中文字幕无码绿巨人| 国产成人久久激情91| 久久精品综合一区二区三区| 久久人人爽人人爽人人av东京热 | 久久久国产亚洲精品| 久久久久人妻精品一区二区三区| 99久久无色码中文字幕| 国产精品成人久久久久久久| 国产精品久久久久久久久软件| 国产麻豆精品久久一二三| 伊人久久综在合线亚洲2019| 精品久久久久久无码不卡| 99久久精品国产高清一区二区| 久久性精品|