Home > Latest topics

Latest topics > nsIVariantを使ってるアドオンが終了していた、と思ったら僕の知識の方が終了していた件

宣伝1。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

宣伝2。Firefox Hacks Rebooted発売中。本書の1/3を使って、再起動不要なアドオンの作り方のテクニックや非同期処理の効率のいい書き方などを解説しています。既刊のFirefox 3 Hacks拡張機能開発チュートリアルと併せてどうぞ。

Firefox Hacks Rebooted ―Mozillaテクノロジ徹底活用テクニック
浅井 智也 池田 譲治 小山田 昌史 五味渕 大賀 下田 洋志 寺田 真 松澤 太郎
オライリージャパン

nsIVariantを使ってるアドオンが終了していた、と思ったら僕の知識の方が終了していた件 - Mar 23, 2010

SCRAPBLOG : JavaScript 製 XPCOM で配列構造・列挙構造のデータをメソッドの戻り値にする

独自に開発したXPCOMコンポーネントに対して配列を渡したり、あるいは戻り値を配列で受け取ったり、ということをやる方法はいくつかある。上記エントリではコメント欄も含めると4つの方法が紹介されていて、そのうちコメント欄にある2つはJavaScriptの配列をそのまま受け渡せるという点で有用だ。特にnsIVariantインターフェースを使うやり方は、戻り値に使う時に余計な引数を定義しなくていいので、実際にそのXPCOMコンポーネントをJavaScriptから使う時にとても使い勝手がいい。

ということでXUL/Migemoでは積極的にnsIVariantを使ってたんだけど、これがMinefield(検証したバージョンは3.7a4pre)で動かなくなってた。

結論から言うと、これはnsIVariantインターフェースのIIDが6c9eb060-8c6a-11d5-90f3-0010a4e73d9aから81e4c2de-acac-4ad6-901a-b5fb1b851a0dに変更されたせいで起こっている問題で、nsIDOMRangeのIIDが変更された時に起こった問題と同様の物だ。

変更が入ったのは昨年9月で、HTML5の新しい仕様に対応するための作業の一環として、何らかの必要があってインターフェースに機能を加えると同時にIIDも変わったらしい。nsIVariantはFROZENなインターフェースじゃないから、nsIDOMRangeの時のようにIIDが元に戻されることは多分あり得ない。よって、考えられる対策は以下のいずれかということになる 。

  • APIをXPCOM経由で提供する事を諦める。Firefox 2以前、Thunderbird 2以前を切り捨てて、JavaScriptコードモジュールとして書き直す。
  • Firefox 3.6以前用とFirefox 3.7以降用とでXPIDLのコンパイル後のバイナリを分けて、Firefoxのバージョン別に2つのXPIファイルを提供するようにする。

JavaScriptコードモジュールにするデメリットは、Thunderbird 2で利用できなくなってしまう点と、APIが変わってしまう点。バイナリを分けるデメリットは、リリースの時の作業がめんどくさくなる(XPIファイルが2つになるので)という点。どっちを選んでも大変なのは変わらない……

APIが変わってしまうことは避けたかったので、結局、後者の方で対処することにした。

前から使ってるXPI生成用シェルスクリプトに起動オプションでサフィックスを指定できるようにして、

こんなショボいスクリプトを作って、前出のスクリプトと一緒に

call xpidl.bat xulrunner-sdk-1.9.2
bash makexpi.sh -n xulmigemo -v 0 -s "1.9.2"

call xpidl.bat xulrunner-sdk-central
bash makexpi.sh -n xulmigemo -v 0 -s "central"

てな感じで実行するようにして(make.bat / make.sh)、MozillaのFTPサイトからXULRunner SDKのファイル一式を入手して

  • xulmigemo
    • make.bat (make.sh)
    • xpidl.bat (xpidl.sh)
    • makexpi.sh
    • install.rdfなど
  • xulrunner-sdk-1.9.2
    • bin
      • xpidl.exe (xpidl)
    • idl
  • xulrunner-sdk-central
    • bin
      • xpidl.exe (xpidl)
    • idl

という感じにファイルを配置するようにした。

XPIを作りたい時にはXULRunner SDKが必要になってしまうけど、スクリプトいっこ走らせれば xulmigemo-mozilla-1.9.2.xpi と xulmigemo-mozilla-central.xpi という風に複数のXPIを出力できるようになったので、リリースにかかる手間は少しは軽減された……のかな……

追記。Gomitaさんのコメントを見て、IDLファイルからincludeの行を消して試してみたら、それでちゃんとコンパイルできた。なんでだ……!!!

えーと。ずっと勘違いしてたんだけど、#include "nsISupports.idl" みたいな行は、interface xmIXMigemoFileAccess : nsISupports てな感じでインターフェース定義の継承元に別のインターフェースを使う場合にだけ必要で、戻り値や引数に使う分には単に interface nsIVariant; とだけ書いておけばいいみたいですね……そうすると、コンパイル時には余計なIIDが含まれなくなって、Firefox 3.6まででも3.7以降でも問題なく使えるXPTファイルが作られるみたい。

まとめ。

  • IDLファイルの書き方を間違えておらず、最小限の記述だけにしてあれば、コンパイルしたXPTファイルはFirefox 3.6まででもFirefox 3.7以降でも使える。
    • 継承元に使うインターフェースはその内容が定義されたIDLファイルをincludeした上で interface インターフェース名; と書く。
    • そうでない物(引数や戻り値でしか使わないインターフェース)は interface インターフェース名; だけ書く。
  • Minefield 3.7におけるnsIVariantのIIDの変更の影響を受けるのは、nsIVariantを継承元としてさらに拡張したインターフェースを定義する場合だけ。

そんなわけで、xmIXMigemo.idlの頭の所はずいぶんスッキリしました。

#include "nsISupports.idl"
#include "nsIObserver.idl"

interface nsIObserver;
interface nsIFile;
interface nsIVariant;
interface nsIDOMWindow;
interface nsIDOMDocument;
interface nsIDOMRange;
interface nsIDOMElement;
interface nsIDOMNode;


/* Utilities: You can use them for your language without additional implementation. */

[scriptable, uuid(4aca3120-ae38-11de-8a39-0800200c9a66)]
interface xmIXMigemoFileAccess : nsISupports
{
(以下略)
分類:Mozilla > XUL, , , , , , , 時刻:13:54 | Comments/Trackbacks (4) | Edit

Comments/Trackbacks

#include "nsIVariant.idl"

自分の拡張機能でもJS製XPCOMで引数や戻り値にnsIVariant型を使っていますが、今のところFirefox 3.6とFirefox 3.7a4pre (Gecko/20100325) の両者でnsIVariant絡みの問題は発生していません。
おかしいなと思って色々調べたのですが、どうやらXPTファイルの元になるIDLファイルに「#include "nsIVariant.idl"」が入っている場合にだけ問題が発生するような気がします。
試しにXUL/Migemoの3つのIDLファイルの「#include "nsIVariant.idl"」を削除してXPTを作ってみたところ、Firefox 3.6と3.7a4preの両方で動作可能なようでした。
そもそも「#include "nsIVariant.idl"」が何を意味しているのか、よくわかっておりませんが…

Commented by Gomita at 2010/03/26 (Fri) 17:37:45

no title

えぇぇぇぇ?!
#include nsIVariant.idl
の行はXULRunner SDKの中にあるnsIVariant.idlを読み込む物で、読み込んでおかないと引数や戻り値の型にnsIVariantを使えないはずなんですが……実際、手元のXULRunner SDKのxpidlでやるとどうしてもそうなりますし。
Gomitaさんはどうやってidlからxptをコンパイルされてるんでしょうか? そのやり方に解決のヒントがある気がします。

Commented by Piro at 2010/03/28 (Sun) 00:51:30

#include "nsIVariant.idl"

使っているSDKはかなり前(Firefox 2.0の頃)から変わっておらず、確か下記のページからダウンロードしたような記憶があります。今はリンク切れになっててダウンロードできませんが。
Gecko SDK - MDC
https://developer.mozilla.org/ja/Gecko_SDK

XPTファイルを作る手順についても、自作スクリプトで機械的にやっているのですが、肝の部分は以下のようなコマンドです。
***\gecko-sdk\bin\xpidl.exe -m typelib -w -v -I ***\gecko-sdk\idl -e components\hoge.xpt components\hoge.idl

ちなみに、自作拡張機能のIDLファイルの中に「#include nsIVariant.idl」の行は入れてませんが、「interface nsIVariant;」という行は入れてあります。fuelIApplication.idlを見てもやはり「#include nsIVariant.idl」の行はありませんですね…
http://mxr.mozilla.org/mozilla-central/source/browser/fuel/public/fuelIApplication.idl

Commented by Gomita at 2010/03/28 (Sun) 01:30:24

no title

あ、上記で「使っているSDK」というのは普段自作拡張機能で使っているSDKのことです。
今回、実験としてXUL/Migemo用のXPTを作ったのは、nsIVariantのIIDが「81e4c2de-acac-4ad6-901a-b5fb1b851a0d」に変わった後のIDLを含むSDKになります。

Commented by Gomita at 2010/03/28 (Sun) 01:37:37

TrackBack ping me at


の末尾に2014年1月19日時点の日本の首相のファミリーネーム(ローマ字で回答)を繋げて下さい。例えば「noda」なら、「2010-03-23_nsivariant.trackbacknoda」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

writeback message: Ready to post a comment.

2014年1月19日時点の日本の首相のファミリーネーム(ひらがなで回答)

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のつぶやき

オススメ

Mozilla Firefox ブラウザ無料ダウンロード