トップ «前の日記(2014-08-12) 最新 次の日記(2014-08-20)» 編集

日々の破片

著作一覧

2014-08-19

_ Firefoxを使うデスクトップアプリケーションのメモ

Firefoxの開発者用資料は、MDNにまとまっていはいるのだが、微妙に情報が古かったり持って回っていたり新しい情報もあるのだが最初に古い情報(ただし現在でも問題なし)がメインにあったりして、決して読みやすくはない。というか、実感として読みやすくなかった。

でも、オープンな情報としては悪いできではない。不足しているものは利用するものが補えば良いだけかも知れない。

というわけで、先週に学んだことをまとめておく。

・Geckoの組み込み

Embedding Mozillaが入口なのだが、どうも壮大な廃墟っぽい。

・XULRunner

そこでさらにいろいろ見ていくと、組み込みをうまく行うためのフレームワークとしてXULRunnerというものを見つけられる。

具体的にはXULRunnerというブートローダーを利用してJavaScriptのコードを動かし、必要に応じてC++で記述したコンポーネントを組み込むためのフレームワークとなっている。ある意味Firefoxはそのインスタンスだ。

独自にWidgetを提供していることが理由なのだろうが、XULはHTMLとは異なるしネイティブなコントロールを指定するようになっている。XULの簡単な例

が、コンポーネントを作るためにSDKを揃えようとしても、SDKのタールボールのビルドに失敗したりドキュメントと実際のライブラリの組み合わせが異なっていたりしてうんざりしてくる。

結局、わかったことはビルド済みXULRunnerを使えば話が早いということと、したがってJavaScriptでコードを書くのは簡単だが、ライブラリやヘッダがうまく構成できないのでC++のコンポーネントを作るのは至難の技だということだった。

・XPCOM

しかしよくよく見ていくと組み込み用APIはCOMそっくりのXPCOMというものでできている。thisポインタをスタックトップに置いた呼び出しということはABIが規定されているのだから最悪ヘッダファイルが無くても問題ないし、dylib(so)との結合なら最低限のエントリポイントさえわかればどうにかなる。が、面倒くさいうえに、サンプルに合わせて作ろうとすると、えらく回り道となってすっかり嫌になった。

XPCOM。ここは能書きだからまあいいのだが、COM同様にIDL(インターフェイス定義言語)を使ってインターフェイスのバイナリデータを作る必要がある(ちょっと微妙でCOMがIDLで生成するのは主としてヘッダとスタブでTypeLibはほぼおまけなのだが、XPCOMの場合はTypeLibの生成のほうがメインとなるようだ)。

でそのためのツールがxpidlなのだがここは罠になっている。確かにある時期までxpidlというツールがあったのだが、今はまともに動かない。

まともに動くxpidlはPythonによるpyxpidlというスクリプトなのだった。

でしばらく格闘してみたがやはりヘッダがどこにあるのかわからなかったり、突然、すべてのチュートリアルの内容を反故にするようなバージョンアップによるインターフェイスの変更が(10年くらい前に)あったりしてうんざりだ。

このあたりはMLベースで開発を進める昭和なコミュニティの問題点としか言いようがない。MLの内容はなかなかサーチエンジンに引っかからないし情報はリアルタイムには良いかも知れないけど10年後に調べるのには向いていない。

そう考えるとWikiが一番のような気がするのだけど。

・js-ctypes

では自前のC/C++というかネイティブコードコンポーネントを利用するにはどうすれば良いかというと、libffiの出番なのだった。MozillaのJavaScript用libffiバインディングがjs-ctypesだ。

というところまでようやくたどり着いて(SDKをビルドするのと自前コンポーネントを作ろうと試行錯誤している時間がやたらと長く、しかもそれは結果的に捨て時間となったわけだが)、FireRubyにたどり着いた。

_ XULRunnerの実行

たとえばJavaのServletコンテナであれば、アプリケーションディレクトリにWEB-INFというディレクトリがあり、その中にweb.xmlという定義ファイルを置き、classesというディレクトリの下にclassファイルをパッケージディレクトリに配置し、jarは直接WEB-INFへ置くといった決まりがある。

XULRunnerも同様に決まりがあって、以下のようにする。ディレクトリ名はおそらく定義ファイル内にも記述するので変えられるように思えるが、変える必要はないのでそのまま使えば地雷を踏む必要もない。

/appname
  application.ini  …… アプリケーションのメタデータ
  chrome.manifest …… chrome(外枠ウィンドウ)の定義位置を示す
  /chrome
     chrome.manifest ……コンテンツの位置を示す
     /content
         main.xul …… DOM定義
         main.js  …… アプリケーションそのもの
  /default/preferences
             prefs.js …… 設定ファイル(たとえばjavascript.options.strictにtrueを設定するなど)

上記の形式で作成し、XULRunnerにapplication.iniのフルパス名を与える。するとmozillaのウィンドウが作成されてmain.jsに制御が移る。

main.jsがロードされる時点ではwindowオブジェクトとdocumentオブジェクトはあるが、まだDOMは構築されていないのでDOMの諸要素に対してイベントハンドラを設置したりはできない。また、windowのloadイベントが呼ばれた時点ではウィンドウが非表示のためalertを呼び出すことはできない。

ただXULRunnerはFirefoxと同時に配布されるようなプログラムではないので別途インストールが必要となる。

XULRunnerの代わりにFirefoxを使うこともできる。その場合は以下のように実行する。

firefox-bin -app (application.iniのフルパス名)

consoleオブジェクトのログを参照できるようにする方法などはDebugging a XULRunner Applicationを参照。-jsconsoleオプションを使う。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

ジェズイットを見習え