2008年9月アーカイブ

Gecko 1.7以前はGeckoの初期化をするために、xpcom.dll内の NS_InitXPCOM2を呼び出す必要があった。 この関数の引数にはnsIDirectoryServiceProviderを指定する必要があり、 しかもこのインターフェースはGREの 場所を返せないといけない。 はっきり行って面倒くさい。 ちゃんと動作させないと一部のインターフェースが動いてくれないので、 面倒くさいが必須の作業なのだ。 まあ面倒くさい。 このインターフェースを含む初期化処理を行う関数を自作ライブラリに用意しているのだが、 初期化用ライブラリのため暗黙の動的メモリ確保を使用するコードを書きたくなかったので、 とても神経を使った。 ていうかNewInstanceクラスメソッドとかはじめて使った。

一方、Gecko 1.8以降には追加関数としてXRE_InitEmbeddingが用意された。 こいつはxul.dll内にある関数なのだが、 非常に面倒くさいnsIDirectoryServiceProviderの実装を 肩代わりしてくれている点において、非常にありがたい。 まあこの関数をxul.dllから持ってくるコードを書かないといけないわけだが、 インターフェースの実装よりははるかに簡単だ。 Gecko内部の関数なので、Geckoの仕様が変わったりとかで初期化の仕方が変わっても、 ちゃんと追従できるのがうれしい。 こういう関数をもっと早く用意してくれれば無駄なコードを核時間が減るんだけどなあ。

そういえば以前nsAStringの実装をDelphiで実現したな。 Gecko 1.7でNS_StringContainerInitその他が実装されたときには、 血の涙を流して喜んだものだ。

nsIWebBrowserのガワの話。 要するにnsIWebBrowserChromeの実装の話。 とりあえず触りだけ。

最低限以下のインターフェースの実装が必要なようだ。

nsIWebBrowserChrome

ガワ本体。ガワなのに本体とはどういうことかと思うが nsIWebBrowser.containerWindownsIWebBrowserChrome型なので仕方ない。

nsIInterfaceRequestor

今ひとつどう説明すればわからないインターフェース。 queryInterfaceによく似たメソッドgetInterfaceを持つ。 getInterfaceで取得したインターフェースは逆変換できる必要はない。 queryInterfaceではあくまで自分自身を返すが、 getInterfaceではプロパティや関数の戻り値を返してもいいことになる。 Mozillaのソースを深く読んではいないのでどう便利なのかはいまいちわからないが、 nsIWebBrowserのガワとしては必須。

とりあえず上の2つのインターフェースのメンバのうち、 nsIInterfaceRequestor.getInterfaceメソッドを queryInterfaceに丸投げして nsIWebBrowserChrome.webBrowserプロパティを実装すれば 残りのメソッドは全部NS_ERROR_NOT_IMPLEMENTEDにしても動く。 getInterfaceを実装しないとFlashもまともに表示されないしリンクも飛べない。 でもgetInterfaceさえ実装すれば動く。 それくらい重要。

はっきり言ってGecko Embedding BasicsnsIInterfaceRequestorがないのは詐欺だろ。

押入れに眠らせておいた自作サーバを復活させるべく、 とりあえず起動して当事どんな構成で動かしていたかを調べてみた。

以下サーバに割り当てられていたIPリスト

続・nsIHttpChannel.asyncOpenが動かないの続き。

nsIHttpChannel.asyncOpenおよび nsIStreamListenerがらみのソースを追っていったところ、 どうやらNS_ProcessNextEventなる関数が怪しいことがわかった。 この関数は現在のスレッドに対して nsIThread.processNextEvent(PR_False)を呼び出す。 こうすることで現在のスレッドにたまっているGeckoイベントを処理することができるわけだ。 こいつを呼び出す処理をたとえばDelphiならApplication.OnIdleに追加すればいい。

が、Gecko1.8まではそんなことをせずともイベントを処理できていたので改悪に見えなくもない。 せっかくのイベント駆動型のOSを使っているのに こんな余計な処理を埋め込みたくないというのが正直な感想だ。 一応Gecko1.9でもSimpleDownload他を動かせる目処が立ったので、 とりあえずそれはよしとする。

まさかnsIWebBrowserのリスナーでも必要だとか言うことはないだろうな。

30分で「続」とかないわ。

nsIHttpChannel.asyncOpenが動かないの続き。 Mozillaおよびxulrunnerのbinフォルダに直接SimpleDownloadをぶち込んで動作確認をした。

自分のブログから自分の別ブログにトラックバックを打ったときに気がついたことだが、 s8.xrea.comはどうやらniku.2ch.netでスパム判定されている模様だ。 これってひょっとするとスパム判定にniku.2ch.netを使っているブログすべてにトラックバックを打てなくなったということじゃないか。 誰だスパム判定をされるような迷惑な行為をしたやつは。 これだから共有サーバーはいやなんだ。

タイトルのごとく。 nsIHttpChannelが動かないわけじゃなくてnsIHttpChannel.asyncOpenが動かない。 nsIHttpChannel.openは問題なく使用可能だったのだが、 nsIHttpChannel.asyncOpenはなぜか動作しない。 引数のaListenerもプロパティのnotificationCallbacksのほうにもgetInterfaceはおろか QueryInterfaceすら呼び出されない。 つまり当然コールバックがないのでデータの読み込みは不可・・・。 SimpleDownloadでも、xpcshellでもだめなので原因がいまいちよくわからない。 SimpleDownloadを作ったときには動いていたので、Geckoのバージョンがあがったので仕様が変わったのだろうか? Frozenインターフェースのはずだからそれはないと思いたい。

以上、メモというより愚痴終わり。

6年位前に通過したことをいまさら記録として残してみるテスト。

begin
  { 初期化 }
  XPCOMGlueStartup(xpcomPath);
  XPCOMGlueLoadXULFunctions(@xulFunctions);
  XRE_InitEmbedding(xpcomDir, nil, nil, nil, 0);

  { WebBrowserオブジェクトの作成 }
  NS_CreateInstance(NS_WEBBROWSER_CONTRACTID, nsIWebBrowser, browser);
  baseWin := browser as nsIBaseWindow;
  baseWin.InitWindow(Pointer(hWnd), nil, 0, 0, rcClient.Right, rcClient.Bottom);
  baseWin.Create();
  baseWin.SetVisibility(PR_True);

  { ページ読み込み }
  navigation := browser as nsINavigation;
  navigation.LoadURI('http://nesitive.net/nesitive/', 0, nil, nil, nil);

  { 気が済んだら終了 }
  XRE_TermEmbedding();
  // XPCOMGlueShutdown(); // なぜかエラーになる
end.

XREを使ったXPCOM利用手順。WinEmbedから抜粋。

  1. XPCOMGlueStartup
  2. XRE_InitEmbedding
  3. なんやかや
  4. XRE_TermEmbedding
  5. おわり

あれ・・・?XPCOMGlueShutdownは?

実行すると実行時例外出ます。以上。

アーカイブ

ウェブページ

Powered by Movable Type 4.21-ja

このアーカイブについて

このページには、2008年9月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2008年7月です。

次のアーカイブは2008年12月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。