目次(I) [折り畳む]
XPCOMの作成 編集
古い情報がたくさん流れています。 新しい情報は何処にあるやら…
SDKの入手 編集
- Firefox,Thunderbird,XULRunner等をビルドする(MOZ_OBJDIR/dist/sdkにsdkができる)
- MozillaのGecko SDKを取ってくる
- http://developer.mozilla.org/ja/docs/Gecko_SDK
(多分、常にここに最新版があります)
- branch
- i586-pc-msvc

- i686-pc-cygwin
(3/30から更新なし) - i686-pc-linux-gnu-gtk2+xft

- i686-pc-linux-gnu
(6/21から更新なし)
- i586-pc-msvc
- trunk(7/2から更新なし)
- branch
JSのXPCOM 編集
計算をするXPCOM、myCalcを作る。
- myCalcはaddというメソッドだけをもつオブジェクト。
- myCalc.addは数値を2つ引数として受け取って、それらの数値を足した結果を返す。
- 例: myCalc.add(3, 4) // -> 7 拡張機能の作成などの部分はスキップして、XPCOMを作る所だけ。
- xxIxxx.idl(myICalc.idl)を作る
- xpidlでxxIxxx.xpt(myICalc.xpt)を作成
- xxxxx.js(myCalc.js)を作成
xxIxxx.idl(myICalc.idl)を作る 編集
#include "nsISupports.idl"
[scriptable, uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)] # ←GUIDを生成して使用
interface myICalc : nsISupports # ←(プレフィクス)I(インターフェース名)
{
long add(in long a, in long b);
};
xpidlでxxIxxx.xpt(myICalc.xpt)を作成 編集
xpidl -m typelib -I c:\xxx_gecko_sdk myICalc.idl
- Iオプションの引数は、Gecko SDK内のidlディレクトリへのパス。これを指定しないとnsISupports.idlのインクルードに失敗する。
xxxxx.js(myCalc.js)を作成 編集
function myCalc(){} // ←(プレフィクス)(インターフェース名)
myCalc.prototype={
get contractID(){
return "@mydomain.example.jp/xpcom-sample/Calc;1"; // ← @(ドメイン)/(コンポーネント名)/(インターフェース名);(バージョン)
},
get classDescription(){
return "This is a Sample";
},
get classID(){
return Components.ID("{yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy}"); // ←GUIDを生成して使用 (インターフェースとは別のもの)
},
add:function(a,b){
return a+b;
},
QueryInterface:function(aIID){
if(!aIID.equals(Components.interfaces.myICalc) && !aIID.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}
var gModule = {
registerSelf: function (aComponentManager, aFileSpec, aLocation, aType)
{
aComponentManager = aComponentManager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
for (var key in this._objects) {
var obj = this._objects[key];
aComponentManager.registerFactoryLocation(obj.CID, obj.className, obj.contractID, aFileSpec, aLocation, aType);
}
},
getClassObject: function (aComponentManager, aCID, aIID)
{
if (!aIID.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
for (var key in this._objects) {
if (aCID.equals(this._objects[key].CID))
return this._objects[key].factory;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
_objects: {
manager: { CID : myCalc.prototype.classID,
contractID : myCalc.prototype.contractID,
className : myCalc.prototype.classDescription,
factory : {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return (new myCalc()).QueryInterface(aIID);
}
}
}
},
canUnload: function (aComponentManager)
{
return true;
}
};
function NSGetModule(compMgr, fileSpec)
{
return gModule;
}
XPCOMの登録と使用 編集
作成したxxIxxxx.xpt(myICalc.xpt)とxxxxxx.js(myCalc.js)を拡張機能の components ディレクトリに置くだけ。拡張機能をインストールしてFirefoxを再起動した後、ユーザープロファイル内のcompreg.datの中に「myCalc」という文字列があれば、正常に登録されている。以下の要領で使用可能。
var calc = Components
.classes["@mydomain.example.jp/xpcom-sample/Calc;1"]
.getService(Components.interfaces.myICalc);
C++のXPCOM 編集
- xxIxxx.idlを作る
- xpidlでxxIxxx.xptとxxIxxx.hを作成
- xxIxxx.hからxxxxx.hとxxxxx.cppとxxxxxModule.cppを作成
- Makefile.inを作成、Firefoxと一緒にビルド
xxIxxx.idlを作る 編集
#include "nsISupports.idl"
[scriptable, uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]
interface xxIxxx : nsISupports
{
long add(in long a, in long b);
};
xpidlでxxIxxx.xptとxxIxxx.hを作成 編集
xpidl -m typelib -I c:\xxx_gecko_sdk xxIxxx.idl xpidl -m header -I c:\xxx_gecko_sdk xxIxxx.idl
xxIxxx.hからxxxxx.hとxxxxx.cppとxxxxxModule.cppを作成 編集
*xxxxx.h 編集
xxIxxx.hにある/* Header file */から/* Implementation file */の手前までをxxxxx.hにコピペ
~xxxxx()をvirtual ~xxxxx()に置換
#ifndef _XX_XXX_H_
#define _XX_XXX_H_
#include "xxIxxx.h"
#define XX_XXX_CONTRACTID "@xxx.xxx.jp/xx_ext/xxx;1"
#define XX_XXX_CLASSNAME "This is Sample"
#define XX_XXX_CID {0x00000000, 0x0000, 0x0000, \
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}
を先頭に追加(XX_XXX_CIDはxxIxxx.hのXXXXX_IIDをコピペする)
#endif //_XX_XXX_H_
を後方に追加
*xxxxx.cpp 編集
xxIxxx.hにある/* Implementation file */からの/* End of implementation class template. */までをxxxxx.cppにコピペ
#include "xxxxx.h"
を先頭に追加
*xxxxxModule.cpp 編集
#include "nsIGenericFactory.h"
#include "xxxxx.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(xxxxx)
static nsModuleComponentInfo components[] =
{
{
XX_XXX_CLASSNAME,
XX_XXX_CID,
XX_XXX_CONTRACTID,
xxxxxConstructor,
},
};
NS_IMPL_NSGETMODULE(xxxxxModule, components)
Makefile.inを作成、Firefoxと一緒にビルド 編集
まだビルドに成功してないので保留
- 適当にXPCOMについてまとめました。誰か足りないところの穴埋め頼みます。 -- by 謎 at 2005-08-08 18:52:49 (月)
C++のXPCOM on Linux 編集
↑と同じく、元ネタはここ。
計算をするXPCOM、myCalcを作る。拡張機能としてインストールし、 ためしに使ってみるところまで。
- myCalcはaddというメソッドだけをもつオブジェクト。
- myCalc.addは数値を2つ引数として受け取って、それらの数値を足した結果を返す。
- 例: myCalc.add(3, 4) // -> 7
Debian GNU/Linux上での話。
ソースはここ
。
以下、作り方。
作業用ディレクトリを作っておくこと。
% mkdir -p xpcom-sample/{content/xpcom-sample,components}
% cd xpcom-sample
拡張機能の作成 編集
いきなりXPCOMの作り方にいくと思ったら大間違い。まずは、XPCOM をインストールする拡張機能を作る。
install.rdf:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>xpcom-sample@cozmixng.org</em:id>
<em:name>XPCOM sample</em:name>
<em:version>0.1</em:version>
<em:description>XPCOM sample</em:description>
<em:creator>Kouhei Sutou</em:creator>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>2.0.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
chrome.manifest:
content xpcom_sample content/ overlay chrome://browser/content/browser.xul chrome://xpcom_sample/content/overlay.xul
インストーラ作成スクリプトも作る。
dist.sh:
#!/bin/sh
cd `dirname $0`
#basename=`basename $PWD`
basename=xpcom-sample
version=`grep '<em:version>' install.rdf | sed -e 's,</\?em:version>,,g'`
version=`echo $version | sed -e 's/[[:space:]]//g'`
xpi=$basename-$version.xpi
if [ -f components/Makefile ]; then
(cd components && make) || exit 1
component_shared="components/myCalc.so"
component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"
fi
xpi_contents="content $components chrome.manifest install.rdf"
rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x \*/.svn/\* || exit 1
dist.shを実行し.xpiを作成する。
% ./dist.sh
カレントディレクトリにxpcom-sample-0.1.xpiが作成されているは ずなので、それをインストール。
% iceweasel xpcom-sample-0.1.xpi
「ツール」→「アドオン」で「XPCOM sample」がインストールされ ていることを確認する。
それでは、準備ができたのでXPCOMを作成していく。
IDLの作成 編集
まずは、IDL、components/myICalc.idlを作成する。XPCOMは components以下に作成すること。そうすると、Firefoxが自動で XPCOMを検出して読み込めるようにしてくれる。そうしないと、リン ク先にあるように手動で登録しなくてはいけなくなって、はまる。
IDL中のuuidはuuidgenで生成する。
% uuidgen c95498ae-16f5-4b46-8713-2cf79e30d4ef
compornts/myICalc.idl:
#include "nsISupports.idl"
[scriptable, uuid(c95498ae-16f5-4b46-8713-2cf79e30d4ef)]
interface myICalc : nsISupports
{
long add(in long a, in long b);
};
.xptと.hの生成 編集
次にIDLから.xptと.hを生成する。.xptはたぶん、このXPCOMはこう いう名前でこういうプロパティを持っていますよ~、とかいう情報 なんだと思う。.hはそのプロトタイプ宣言とか。(ここは適当に書 いている)
.xpiと.hはxpidlを使って作る。これは.idlを更新するたびに行う必 要がある。たぶん、これからたくさん起こることなのでMakefileを 作っておく。
ここではXULRunnerを使っている(Debianではxulrunnerパッケー ジ)。他の環境でやる場合はGECKO_PATHとかGECKO_XXX_PATHを変更 する必要があるだろう。
components/Makefile:
GECKO_PATH = /usr/lib/xulrunner GECKO_SDK_PATH = $(GECKO_PATH)/sdk GECKO_IDL_PATH = $(GECKO_SDK_PATH)/idl XPIDL = $(GECKO_PATH)/xpidl IDL = myICalc.idl XPT = myICalc.xpt IHEADER = myICalc.h all: $(XPT) $(IHEADER) $(XPT): $(IDL) $(XPIDL) -m typelib -I$(GECKO_IDL_PATH) $(IDL) $(IHEADER): $(IDL) $(XPIDL) -m header -I$(GECKO_IDL_PATH) $(IDL) clean: rm -f $(XPT) $(IHEADER)
実は最初に作ったdist.shにはcomponentsでmakeするコードも入って いる。ということで、dist.shを実行して.xpiを生成し、再びインス トールする。
% ./dist.sh /usr/lib/xulrunner/xpidl -m typelib -I/usr/lib/xulrunner/sdk/idl myICalc.idl /usr/lib/xulrunner/xpidl -m header -I/usr/lib/xulrunner/sdk/idl myICalc.idl % iceweasel xpcom-sample-0.1.xpi
.xptが認識されているかどうかは以下のようにして確認できる。
% grep xpcom-sample ~/.mozilla/firefox/*/xpti.dat
以下のような行が出たら認識されている。
4,.../extentions/xpcom-sample@cozmixng.org/components
XPCOMの実装 編集
それでは、足し算をするメソッドaddを持つmyCalcオブジェクトを実 装する。今まではファイル名に(たぶん)インターフェイス (Interface)を表すIをつけていたけど、これからはつけない。
まずは、myCalc.hを作成する。ここでもUUIDが必要になるので事前 に生成しておく。
% uuidgen 8931dfd3-edf3-4b7d-bd44-1da72064f0dc
また、以下のようなフォーマットに変換する必要がある。
8931dfd3-edf3-4b7d-bd44-1da72064f0dc
↓
8931dfd3 edf3 4b7d bd 44 1d a7 20 64 f0 dc
↓
0x8931dfd3 0xedf3 0x4b7d 0xbd 0x44 0x1d 0xa7 0x20 0x64 0xf0 0xdc
↓
{0x8931dfd3, 0xedf3, 0x4b7d, {0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}
これをRubyで書くとこう。
split-uuid.rb:
#!/usr/bin/env ruby
ARGV.each do |uuid|
uuid_components = uuid.split(/-/)
first_components = uuid_components.slice!(0, 3)
second_components = []
uuid_components.each do |uuid_component|
second_components.concat(uuid_component.scan(/../))
end
first_components = first_components.collect do |component|
"0x#{component}"
end.join(", ")
second_components = second_components.collect do |component|
"0x#{component}"
end.join(", ")
puts "{#{first_components}, {#{second_components}}}"
end
あるいはこう。
split-uuid2.rb:
#!/usr/bin/env ruby
ARGV.each do |uuid|
uuid_components = uuid.split(/-/)
first_components = uuid_components.slice!(0, 3)
second_components = uuid_components.inject([]) do |result, component|
result + component.scan(/../)
end
first, second = [first_components, second_components].collect do |components|
components.collect do |component|
"0x#{component}"
end.join(", ")
end
puts "{#{first}, {#{second}}}"
end
手動でもいいのでとにかく以下のふたつの形式のUUIDを生成する。
8931dfd3-edf3-4b7d-bd44-1da72064f0dc
{0x8931dfd3, 0xedf3, 0x4b7d, {0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}
ヘッダファイルの雛型はcomponents/myICalc.hにあるので、それを コピーする。
components/myCalc.h:
#ifndef __MYCALC_H__
#define __MYCALC_H__
#include "myICalc.h"
#define MY_CALC_CONTRACT_ID "@cozmixng.org/xpcom-sample/Calc;1"
#define MY_CALC_CLASS_NAME "Calculator"
#define MY_CALC_CID_STR "8931dfd3-edf3-4b7d-bd44-1da72064f0dc"
#define MY_CALC_CID \
{0x8931dfd3, 0xedf3, 0x4b7d, \
{0xbd, 0x44, 0x1d, 0xa7, 0x20, 0x64, 0xf0, 0xdc}}
class myCalc : public myICalc
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MYICALC
myCalc();
private:
~myCalc();
protected:
/* additional members */
};
#endif
C++の雛型もcomponents/myICalc.hにあるので、それをコピーして、 addを実装する。
components/myCalc.cpp:
#include "mozilla-config.h"
#include "myCalc.h"
NS_IMPL_ISUPPORTS1(myCalc, myICalc)
myCalc::myCalc()
{
/* member initializers and constructor code */
}
myCalc::~myCalc()
{
/* destructor code */
}
/* long add (in long a, in long b); */
NS_IMETHODIMP myCalc::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)
{
*_retval = a + b;
return NS_OK;
}
components/Makefileを書き換えて、実装をコンパイルできるように する。
components/Makefile:
CXX = c++ CXXFLAGS = -g -Wall -fno-rtti -fno-exceptions -shared GECKO_PATH = /usr/lib/xulrunner GECKO_SDK_PATH = $(GECKO_PATH)/sdk GECKO_IDL_PATH = $(GECKO_SDK_PATH)/idl GECKO_INCLUDE_PATH = $(GECKO_SDK_PATH)/include GECKO_LIB_PATH = $(GECKO_SDK_PATH)/lib XPIDL = $(GECKO_PATH)/xpidl GECKO_INCLUDES = -I$(GECKO_INCLUDE_PATH) GECKO_CFLAGS = -DXPCOM_GLUE $(GECKO_INCLUDES) GECKO_LDFLAGS = -L$(GECKO_LIB_PATH) GECKO_LIBS = -lxpcomglue \ -lnspr4 \ -lplds4 OBJS = myCalc.o IDL = myICalc.idl XPT = myICalc.xpt IHEADER = myICalc.h SHARED = myCalc.so all: $(XPT) $(IHEADER) $(SHARED) $(XPT): $(IDL) $(XPIDL) -m typelib -I$(GECKO_IDL_PATH) $(IDL) $(IHEADER): $(IDL) $(XPIDL) -m header -I$(GECKO_IDL_PATH) $(IDL) $(SHARED): $(IHEADER) $(OBJS) $(CXX) $(CXXFLAGS) $(GECKO_LDFLAGS) -o $(SHARED) $(OBJS) $(GECKO_LIBS) clean: rm -f $(XPT) $(IHEADER) $(OBJS) $(SHARED) .cpp.o: $(CXX) $(CXXFLAGS) $(GECKO_CFLAGS) -c $<
dist.shを実行してコンパイルするとMozillaのヘッダファイルで warningがでるのが嫌な感じ。
% ./dist.sh c++ -g -Wall -fno-rtti -fno-exceptions -shared -DXPCOM_GLUE -I/usr/lib/xulrunner/sdk/include -c myCalc.cpp /usr/lib/xulrunner/sdk/include/nsISupportsBase.h:80: warning: ‘class nsISupports’ has virtual functions but non-virtual destructor /usr/lib/xulrunner/sdk/include/nsIProgrammingLanguage.h:32: warning: ‘class nsIProgrammingLanguage’ has virtual functions but non-virtual destructor /usr/lib/xulrunner/sdk/include/nsIClassInfo.h:33: warning: ‘class nsIClassInfo’ has virtual functions but non-virtual destructor myICalc.h:25: warning: ‘class myICalc’ has virtual functions but non-virtual destructor c++ -g -Wall -fno-rtti -fno-exceptions -shared -L/usr/lib/xulrunner/sdk/lib -o myCalc.so myCalc.o -lxpcomglue -lnspr4 -lplds4
これでcomponents/myCalc.soができる。
でも、まだこれだけじゃだめ。
XPCOMの登録 編集
↑で作った共有ライブラリが読み込まれたときに、中に入っている XPCOMを登録する機能が必要になる。その機能を components/myCalcModule.cppとして実装する。
components/myCalcModule.cpp:
#include "nsIGenericFactory.h"
#include "myCalc.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(myCalc)
static nsModuleComponentInfo components[] =
{
{
MY_CALC_CLASS_NAME,
MY_CALC_CID,
MY_CALC_CONTRACT_ID,
myCalcConstructor,
}
};
NS_IMPL_NSGETMODULE("myCalcModule", components)
また、components/MakefileのOBJSにも加えておく。
components/Makefile:
... OBJS = myCalc.o myCalcModule.o ...
今回はmyCalcのみ登録しているが、複数のXPCOM(オブジェクトって いった方がいい?)を一つの共有ライブラリに入れて、まとめて登 録することもできる。たぶん。試していないけど。
いつものようにdist.shでコンパイルし、.xpiを更新し、再インストー ル。
% ./dist.sh ... % iceweasel xpcom-sample-0.1.xpi
myCalcが登録されているかどうかは以下のようにして確認できる。
% grep myCalc ~/.mozilla/firefox/*/compreg.dat
以下のようなのがでればOK。UUIDがmyCalc.hに書いたものと同じも のであることを確認する。
abs:/.../xpcom-sample@cozmixng.org/components/myCalc.so,1173322260000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs:/.../myCalc.so
テスト用インターフェイスの追加 編集
対話型でJavaScriptの式を評価するインターフェイスがあればいい んだけど、あるかどうかわからない(エラーコンソールは毎回評価 コンテキストが違うみたいだからダメ)ので、作ったXPCOMを使うテ スト用のインターフェイスを作る。メニューバーにメニューを追加 し、myCalc.addを使って3 + 4を実行するJavaScriptを実行するよう にする。
content/overlay.xul:
<?xml version="1.0"?>
<overlay
id="test-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<menubar id="main-menubar">
<menu label="XPCOM sample">
<menupopup>
<menuitem label="Call sample XPCOM"
oncommand="
(function () {
var obj;
try {
const cid = '@cozmixng.org/xpcom-sample/Calc;1';
obj = Components.classes[cid].createInstance();
obj = obj.QueryInterface(Components.interfaces.myICalc);
} catch (err) {
alert(err);
return;
}
alert('3 + 4 = ' + obj.add(3, 4));
})();
"/>
</menupopup>
</menu>
</menubar>
</overlay>
.xpiを更新し、再インストールする。
% ./dist.sh % iceweasel xpcom-sample-0.1.xpi
「XPCOM sample」→「Call sample XPCOM」を実行して 「3 + 4 = 7」というアラートウィンドウがでたら成功。
C++のXPCOM on Mac OS X 編集
↑の続き。
ソースはここ
。
PPC版でもIntel版でも動くユニバーサルバイナリ(?)を作る。
必要なもの 編集
- Xcode 2.4.1(使ったのが2.4.1ってだけ)
- Mac OS X 10.4.8(使ったのが10.4.8ってだけ)
- Firefox本体
- gecko-sdk

ビルドスクリプトの更新 編集
Mac OS Xでは、GCCではなくてXcodeを使ってコンパイルする。その ため、Linux用のMakefileは使用できない。また、それに対応するた めにdist.shを変更する必要がある。
Xcodeのプロジェクトはcomponents/myCalc.xcodeproj/に配置するこ とにする。
dist.sh:
#!/bin/sh
cd `dirname $0`
if [ -x "`which gnused`" ]; then
SED=gnused
else
SED=sed
fi
#basename=`basename $PWD`
basename=xpcom-sample
version=`grep '<em:version>' install.rdf | $SED -e 's,</\?em:version>,,g'`
version=`echo $version | $SED -e 's/[[:space:]]//g'`
xpi=$basename-$version.xpi
case `uname` in
Linux)
(cd components && make) || exit 1
component_shared="components/myCalc.so"
;;
Darwin)
build_type=Release
xcodebuild_args="-project myCalc.xcodeproj -configuration $build_type"
(cd components && xcodebuild $xcodebuild_args) || exit 1
component_shared="components/libmyCalc.dylib"
cp components/build/$build_type/libmyCalc.dylib $component_shared
;;
*)
echo "Unknown environment"
exit 1
;;
esac
component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"
xpi_contents="content $components chrome.manifest install.rdf"
rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x \*/.svn/\* || exit 1
.xptと.hの生成 編集
Mac用のgecko-sdkに入っているxpidlは古いglibとlibIDLでコンパイ ルされている。これは以下のようにすれば確認できる。
% otool -L gecko-sdk/bin/xpidl gecko-sdk/bin/xpidl: /sw/lib/libglib-1.2.0.dylib (compatibility version 1.0.0, current version 1.10.0) /sw/lib/libIDL-0.6.0.dylib (compatibility version 5.0.0, current version 5.4.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 71.1.4)
このくらいのバージョンのやつは最近のFinkとかMacPortsとかでは 入手困難。なので、Mac OS Xでは.idlから.xptと.hを生成するのは 諦めよう。Linuxとかで生成した.xptと.hを持ってきましょう。
あるいは、
xpidl実行Webサービス
を
利用する。詳しい使いかたは
xpidl.cgiの使いかた
を参照。
Xcodeプロジェクトの作成 編集
- ファイル→新規プロジェクト
- 空のプロジェクト
- プロジェクト名: myCalc
- ディレクトリ: .../xpcom-sample/components/
- 左ペインのmyCalcってとこで右クリック
- 追加→新規ターゲット
- BSD/Dynamic Library
- ターゲット名:myCalc
- 「ターゲットmyCalcの情報」とかいうウィンドウがでるので消す
- 左ペインのmyCalcってとこで右クリック
- 追加→既存のファイル
- myCalc.cpp, myCalc.h myCalcModule.cpp, myCalc.hを選択してまとめて追加
- プロンプトがでたらデフォルトのまま追加(ターゲットに追加でさっき作ったmyCalcにチェックが入っていることを確認)
- 左ペインのmyCalcってとこでダブルクリック
- 「プロジェクトmyCalcの情報」とかいうウィンドウがでる
- 「一般」タブ→「ターゲットSDKを使用したクロス開発」: 「Mac OS X 10.4 (Universal)」
- 「ビルド」タブ→「構成」: 「全ての構成」
- 「アーキテクチャ」→下のほうにある「編集」ボタン: 「PowerPC」と「Intel」にチェック
- 「ヘッダ検索パス」→下のほうにある「編集」ボタン: 下にある「+」ボタンを押して項目を増やし、gecko-sdk/includeへパスを通す
- 相対パスにする場合はソース中ではcomponents/ディレクトリから指定
- サンプルソース中ではトップディレクトリ(xpcom-sample)と同じディレクトリにgecko-sdkが展開されていると仮定している
- 「ライブラリ検索パス」→下のほうにある「編集」ボタン: 下にある「+」ボタンを押して項目を増やし、Firefox.app/Contents/MacOSへパスを通す
- サンプルソース中では/Applications/以下にFirefox.appがインストールされていると仮定している
- 「他のリンカオプション」→下のほうにある「編集」ボタン: 下にある「+」ボタンを5回押して項目を増やし、それぞれ「-lxpcom_core」、「-lxpcom」、「-lnspr4」、「-lplds4」、「-lplc4」を追加
- メニューから「ビルド」→「全てのターゲットをクリーニング」
- メニューから「ビルド」→「ビルド」
- メインウィンドウの左ペインの「エラーと警告」を見て警告・エラーが出ていないことを確認
インストール 編集
いつものようにdist.shを実行して.xpiを作成する。
% ./dist.sh
インストールするにはできたxpcom-sample-0.1.xpiをFirefoxにドラッ グする。うまくインストールされていればメニューに「XPCOM sample」がでて、「Call sample XPCOM」をやって「3 + 4 = 7」と いう警告ウィンドウが出れば成功。
コマンドラインから確認するにはLinuxと同じようにこんな感じ。
% grep myICalc ~/Library/Application\ Support/Firefox/Profiles/*/xpti.dat
こんなのがでてくれば.xptのインストールは成功している。
142,myICalc.xpt,6,134,1173341340000
1294,myICalc,{c95498ae-16f5-4b46-8713-2cf79e30d4ef},142,-1,1
XPCOMがインストールされているかはこう。
% grep myCalc ~/Library/Application\ Support/Firefox/Profiles/*/compreg.dat
こんなのがでてくればOK。
abs:/.../xpcom-sample@cozmixng.org/components/libmyCalc.dylib,1173345060000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs:/.../libmyCalc.dylib
C++のXPCOM on Windows 編集
↑の続き。
ソースはやっぱりここ
。
Microsoft Visual Studio 8で作る。CランタイムDLL(MSVCR80.dll)がない環境でも動くようにする。
必要なもの 編集
- Microsoft Visual Studio 8
- Windows XP
- Cygwin: dist.shとかgrepとかを使わないならいらない。
- gecko-sdk

ビルドスクリプトの更新 編集
WindowsではXPCOMの拡張子が.soではなく.dllになる。また、Visual Studioでは Makefileではなくて、ソリューションファイルを使ってコンパイルする。それら に対応するためにdist.shを変更する必要がある。
Visual Stuido 8のソリューションファイルはcomponents/myCalc/myCalc.slnに 配置することにする。また、devenv.exe(Visual Studio 8のコマンド名)にパ スが通っていない場合はC:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exeにあると仮定する。
dist.sh:
#!/bin/sh
cd `dirname $0`
if [ -x "`which gnused 2>&1 /dev/null`" ]; then
SED=gnused
else
SED=sed
fi
#basename=`basename $PWD`
basename=xpcom-sample
version=`grep '<em:version>' install.rdf | $SED -e 's,</\?em:version>,,g'`
version=`echo $version | $SED -e 's/[[:space:]]//g'`
xpi=$basename-$version.xpi
case `uname` in
Linux)
(cd components && make) || exit 1
component_shared="components/myCalc.so"
;;
Darwin)
build_type=Release
xcodebuild_args="-project myCalc.xcodeproj -configuration $build_type"
(cd components && xcodebuild $xcodebuild_args) || exit 1
component_shared="components/libmyCalc.dylib"
cp components/build/$build_type/libmyCalc.dylib $component_shared
;;
CYGWIN*)
build_type=Release
if which devenv > /dev/null; then
DEVENV="devenv"
else
DEVENV="/cygdrive/c/Program Files/Microsoft Visual Studio 8/Common7/IDE/devenv.exe"
fi
"$DEVENV" /Build $build_type components/myCalc/myCalc.sln || exit 1
component_shared="components/myCalc.dll"
cp components/myCalc/$build_type/myCalc.dll $component_shared
;;
*)
echo "Unknown environment"
exit 1
;;
esac
component_xpt="components/myICalc.xpt"
components="$component_xpt $component_shared"
xpi_contents="content $components chrome.manifest install.rdf"
rm -f $xpi
zip -q -r -9 $xpi $xpi_contents -x \*/.svn/\* || exit 1
.xptと.hの生成 編集
Windows用のgecko-sdkに入っているxpidlは古いglibとlibIDLでコンパイルされ ている。これは以下のようにすれば確認できる。
% objdump -p ../gecko-sdk/bin/xpidl.exe | grep -i dll
DllCharacteristics 00000000
vma: Hint Time Forward DLL First
DLL Name: libIDL-0.6.dll
DLL Name: glib-1.2.dll
DLL Name: MSVCRT.dll
このくらいのバージョンのやつをインストールするくらいなら
スタティックリンクされたxpidl
を拾ってくるか、あきらめてLinuxとかで生成した.xptと.hを持ってきた方がい
いでしょう。
あるいは、
xpidl実行Webサービス
を
利用する。詳しい使いかたは
xpidl.cgiの使いかた
を参照。
xpidlのオプションはLinuxと同じなので省略。
Visual Studioソリューションの作成 編集
- ファイル→新規作成→プロジェクト
- Visual C++→全般→空のプロジェクト
- プロジェクト名: myCalc
- 場所: .../xpcom-sample/components/
- ソリューションのディレクトリを作成: チェックをはずす
- 完了
- 左ペインのmyCalc→ソースファイルで右クリック
- 追加→既存の項目→上のフォルダにいってmyCalc.cppとmyCalcModule.cppを選択→追加
- 左ペインのmyCalc→ヘッダーファイルで右クリック
- 追加→既存の項目→上のフォルダにいってmyCalc.hとmyICalc.hを選択→追加
- プロジェクト→myCalcのプロパティ
- 左上のドロップダウンリストの構成: すべての構成
- 構成プロパティ→全般→構成の種類
- ダイナミック ライブラリ (.dll)
- 構成プロパティ→C/C++→全般→追加のインクルードディレクトリ
- ..\..\..\gecko-sdk\include(xpcom-sampleと同じレベルにgecko-sdkがあるとする)
- 構成プロパティ→リンカ→全般→追加のライブラリディレクトリ
- ..\..\..\gecko-sdk\lib(xpcom-sampleと同じレベルにgecko-sdkがあるとする)
- 構成プロパティ→リンカ→入力→追加の依存ファイル
- xpcomglue_s.lib xpcom.lib nspr4.lib
- 構成をRleaseにしてlibcmt.libも追加
- 構成をすべての構成に戻す
- 構成プロパティ→リンカ→入力→特定のライブラリの無視
- MSVCRT
- 構成プロパティ→リンカ→マニフェスト→マニフェストの生成
- いいえ
インストール 編集
いつものようにdist.shを実行して.xpiを作成する。
% ./dist.sh
インストールするにはできたxpcom-sample-0.1.xpiをFirefoxにドラッ グする。うまくインストールされていればメニューに「XPCOM sample」がでて、「Call sample XPCOM」をやって「3 + 4 = 7」と いう警告ウィンドウが出れば成功。
コマンドラインから確認するにはLinuxと同じようにこんな感じ。
% grep myICalc /cygdrive/c/Documents\ and\ Settings/$USER/Application\ Data/Mozilla/Firefox/Profiles/*/xpti.dat
こんなのがでてくれば.xptのインストールは成功している。
4,myICalc.xpt,3,134,1173668700000
587,myICalc,{c95498ae-16f5-4b46-8713-2cf79e30d4ef},4,-1,1
XPCOMがインストールされているかはこう。
% grep myCalc /cygdrive/c/Documents\ and\ Settings/$USER/Application\ Data/Mozilla/Firefox/Profiles/*/compreg.dat
こんなのがでてくればOK。
abs:C:\...\xpcom-sample@cozmixng.org\components\myCalc.dll,1173763800000
{8931dfd3-edf3-4b7d-bd44-1da72064f0dc},,,,abs:C:\...\myCalc.dll
コメント 編集
- Add -> add. インターフェースのメンバ名は基本的にlower camel
。ただしヘッダファイル生成時には自動的に先頭大文字に変換される、はず。 -- nanto_vi 2007年03月08日 (木) 21時51分35秒 New!