C ++でFirefoxにコンポーネントを書き込む方法

FirefoxのコンポーネントをC ++で作成し、後でJavaScript拡張機能から、または通常のWebページからでも使用できるようにする方法。

背景


IEとFirefox用のツールバーを作成する必要がありました。 C-dllkaによって実装された非標準のバイナリプロトコルが使用されたという事実によって、すべてが複雑になりました。 C#(IE用のツールバーを作成した)からそれを使用することは問題ではありませんでしたが、FFの場合、Wrapperを作成する必要がありました。これは、データをdllに渡して結果を返すjavascriptからアクセスできるXPCOMコンポーネントです。
XPCOMはMicrosoftのMozillaのCOMの類似物であり、ほとんど何もCOMとは異なります。 一般的に、Mozillaは、よく説明された馴染みのあるCOMの代わりに、自転車を発明することを決めた理由はあまり明確ではありませんが、そのようになりました。開発者は、すべてをそのまま受け入れる必要があります。
オープンソースは素晴らしいですが、ドキュメントに出会うまで、実用的な例が不足しています。 ところで、インターネット上でXPCOMコンポーネントの4つの例を見つけましたが、どれも機能しませんでした。 さらに、最新のものは2006年のもので、説明には古いバージョンのXULRunnerが含まれており、議論では、たとえば、「新しいFirefox 1.3」との互換性に関する質問と、「動作させるには?」

行こう!


  1. まず、環境を把握しましょう。
    コマンドラインでsubst o: d:\myworkfolder\_firefoxを実行します-必要なすべてのファイルをこのフォルダーに追加します。
    このコマンドをbatファイルに書き込むこともできます。
  2. 最新のXULRunner(現在1.9.0.6)をダウンロードします-release.mozilla.org/pub/mozilla.org/xulrunner/releases
    SDKが必要です。 Oにダウンロードして解凍します:\ xulrunner-sdk
  3. 次の内容でO:\ console.batを作成します。
    set path=%path%;O:\xulrunner-sdk\bin;O:\xulrunner-sdk\sdk\bin
    cmd.exe

    (念のため、突然手で何かをする必要があります)
  4. フォルダO:\ dll-srcを作成します。その中にIDemo.idlがあります
    #include "nsISupports.idl"
    #include "nsrootidl.idl"

    [ scriptable , uuid ( CB934085 - D019 - 47d5 - A6F0 - 623885873281 ) ]

    interface IDemo : nsISupports
    {
    long func1 ( in long inP , out long outP ) ;

    long func2 ( in wstring inP , out wstring outP ) ;
    } ;


  5. 同じ場所で、build-pre.batとbuild-post.batの2つのbatファイルを作成します。 2番目を空のままにして、最初の部分に次のように記述します。
    set path=%path%;O:\xulrunner-sdk\bin;O:\xulrunner-sdk\sdk\bin
    xpidl -IO:\xulrunner-sdk\idl -m header IDemo.idl
    xpidl -IO:\xulrunner-sdk\idl -m typelib IDemo.idl

    idlファイルでは、xpidlを使用して、インターフェイスのヘッダーとxptの説明が自動的に生成されます(Microsoft .tlbファイルに類似)
  6. 新しいWin32 / DLLライブラリ/空のプロジェクトを作成します

  7. build-pre.batを起動し、結果のIDemo.hをプロジェクトに転送します。
  8. VSでファイルDemo.hを作成し、IDemo.hからテンプレートをコピーします。 私たちはそれを人間の形にします:
    #ifndef _DEMO_H_
    #define _DEMO_H_

    #include "IDemo.h"

    #define DEMO_CONTRACTID "@demo.com/XPCOMDemo/Demo;1"
    #define DEMO_CLASSNAME "XPCOM Demo LOL"
    #define DEMO_CID { 0xcb934086 , 0xd019 , 0x47d5 , { 0xa6 , 0xf0 , 0x62 , 0x38 , 0x85 , 0x87 , 0x32 , 0x81 } }

    class Demo : public IDemo
    {
    public :
    NS_DECL_ISUPPORTS
    NS_DECL_IDEMO

    Demo ( ) ;

    virtual ~ Demo ( ) ;
    } ;

    #endif


  9. VSでファイルDemo.cppを作成し、そこにIDemo.hからコメント部分をコピーします-既に実装テンプレートがあります。 クラスの名前を変更します。
    #include "Demo.h"
    #include < nsMemory . h >
    #include < nsStringAPI . h >

    NS_IMPL_ISUPPORTS1 ( Demo , IDemo )

    Demo : : Demo ( ) {
    }

    Demo : : ~ Demo ( ) {

    }
    NS_IMETHODIMP Demo : : Func1 ( PRInt32 inP , PRInt32 * outP , PRInt32 * _retval ) {
    if ( inP > 100 ) {
    * _retval = 1 ;
    * outP = 0 ;
    } else {
    * _retval = 0 ;
    * outP = inP * 2 ;
    }
    return NS_OK ;
    }
    NS_IMETHODIMP Demo : : Func2 ( const PRUnichar * inP , PRUnichar * * outP , PRInt32 * _retval ) {
    const wchar_t * msg = L "" ;
    * outP = ( PRUnichar * ) nsMemory : : Clone ( msg , ( wcslen ( msg ) + 1 ) * sizeof ( wchar_t ) ) ;

    * _retval = 0 ;
    return NS_OK ;
    }

  10. VSでファイルDemoModule.cppを作成します。
    これは、メインファイルであり、アプリケーションへのエントリポイントです。 ここでは、モジュールが実装するコンポーネントをXPCOM'aのコアに示します。
    #include "nsIGenericFactory.h"
    #include "Demo.h"

    NS_GENERIC_FACTORY_CONSTRUCTOR ( Demo )

    static nsModuleComponentInfo components [ ] =

    {
    {
    DEMO_CLASSNAME ,
    DEMO_CID ,
    DEMO_CONTRACTID ,
    DemoConstructor ,

    }
    } ;

    NS_IMPL_NSGETMODULE ( "DemoModule" , components )



  11. プロジェクトのプロパティを開く
    C / C ++-一般-追加のインクルードディレクトリは、O:\ xulrunner-sdk \ sdk \ include;と書きます; O:\ xulrunner-sdk \ include
    C / C ++-プリプロセッサー-プリプロセッサー定義の追加; XPCOM_GLUE
    C / C ++-高度-mozilla-config.hを記述するForce Includes
    リンカ-追加のライブラリディレクトリはOを書き込みます:\ xulrunner-sdk \ sdk \ lib
    リンカー-入力-追加の依存関係-書き込みxpcom.lib nspr4.lib xpcomglue_s.lib
    ビルドイベント-ビルド前イベント-コマンドライン-O:\ dll-src \ build-pre.batを書き込みます
    ビルドイベント-ビルド後イベント-コマンドライン-O:\ dll-src \ build-post.batを書き込みます
  12. Firefoxのショートカットを作成します。
    それを行い、プロパティに次のように記述します: "C:\ Program Files \ Mozilla Firefox \ firefox.exe" -no-remote -P dev
    始めます。 プロファイルマネージャーが開きました。devプロファイルを作成し、フォルダーを手動で指定します。C:\ Documents and settings \ test \ Application Data \ Mozilla \ Firefox \ Profiles \ dev1(「作成」ボタンで作成)。
    Firefoxが起動し、起動したら閉じます
  13. ここでbuild-post.batを編集します。
    set path=%path%;O:\xulrunner-sdk\bin;O:\xulrunner-sdk\sdk\bin

    del /f "C:\Documents and Settings\test\Application Data\Mozilla\Firefox\Profiles\dev\xpti.dat"
    del /f "C:\Documents and Settings\test\Application Data\Mozilla\Firefox\Profiles\dev\compreg.dat"

    copy /Y IDemo.xpt "C:\Program Files\Mozilla Firefox\components\"
    copy /Y debug\Demo.dll "C:\Program Files\Mozilla Firefox\components\"

  14. プロジェクトをビルドします!
  15. ファイルを作成しますO:\ demo.html
    (コードは部分的に与えられます)
    netscape . security . PrivilegeManager . enablePrivilege ( "UniversalXPConnect" ) ;
    obj = Components . classes [ "@demo.com/XPCOMDemo/Demo;1" ] . createInstance ( ) ; // ? Demo.h

    myobject = obj . QueryInterface ( Components . interfaces . IDemo ) ;
    var x = { } ;

    var res = myobject . func1 ( 10 , x ) ;
    alert ( 'func1(10,x) returned ' + res + '. x is ' + x . value ) ;

    res = myobject . func2 ( "asd" , x ) ;
    alert ( 'func2("ads",x) returned ' + res + '. x is ' + x . value ) ;

  16. ショートカットでfirefoxを実行し、ファイルを開きます。// o:\ demo.html
  17. ボタンをクリックして、UNSAFEに関する質問に同意し、結果を確認します。
    UNSAFEに関する質問は、「PrivilegeManager.enablePrivilege」の行で発生します。この行は、XPCOMコンポーネントを操作する許可を要求します。もちろん、Webページに含めるべきではありません。
    Firefox拡張機能(任意のツールバー)を作成すると、すでにXPCOMでの作業が許可されています。 したがって、拡張コードにこの行があってはならず、警告は表示されず、すべてが無音で機能します。
  18. やった! うまくいく!


PS1 すべてのプロジェクトファイルは、このリンクからダウンロードできます(82 kb)
PS2。 「インターフェイス」(または複数)があり、このインターフェイスを実装する「コンポーネント」があります。 それぞれに独自のUIDがあります。 UIDを生成するには、VSのGuidgenが必要です。通常、「C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \ Bin \ guidgen.exe」にあります。 この例に示されている以外のUIDを生成するには、guidgenを実行し、そこで3番目のオプションを選択してコピーし、手でIDemo.idlに貼り付ける必要があります。 次に、別のIDを生成し、Demo.hにコピーします。 Demoコンポーネントにこだわらないでコンポーネントを作成する場合は、これを行う必要があります。
PS3 XPCOMのidlファイルはCOMのidlファイルとは異なるため、Microsoftのtlbimpおよびmidlユーティリティはこれらのidlファイルを理解しません。 プロジェクトにIDemo.idlを追加する場合、そのプロパティに「コンパイルしない」を設定することを忘れないでください。

Source: https://habr.com/ru/post/J53312/


All Articles