ENGLISH page is here.
GET DinopSearchBar
サイト内検索:
HOME
VC++ TIPS
ダウンロード
DinopExifReader
DinopSearchBar
DinopSearchBar mini
DinopTabbingBar
for Firefox
大阪湾の生き物
甲子園浜の自然
甲子園浜の干潟
甲子園浜の水中
甲子園浜の野鳥
近畿の山々
植物図鑑
箕面マップ
水中機材
カメラ
ランキング
望遠鏡の世界
顕微鏡の世界
Googleのすべて
GoogleマップAPI
ニュース
読んだ本
日記
変な料理の作り方
遺伝子操作
論文紹介
デイトレード
自動売買でFX
ネットで小遣い稼ぎ
Solaris
電子工作
その他
問い合わせ
VC++用コード集
大阪湾の生き物
水中用機材
since:2000/11/15
dinopcom@gmail.com
www.dinop.comは
だいのっぷ・どっと・こむ
と読んでください。







« VC++でのXPCOM作成(その1) | メイン | VC++用XPCOM/xpiパッケージ作成ウイザード »

VC++でのXPCOM作成(その2)




はじめに

 Firefox(Mozilla)などの機能をC++によって拡張することができるXPCOMの作り方を紹介する。 ここでは具体的なDLLの作成方法についてを記す。前段階で準備を行っていない場合は「その1」 を参考にすること。



プロジェクトの作成

 Win32プロジェクトとして空のDLLプロジェクトを作成する。

 Visual C++を起動し、「ファイル」メニューの「新規作成」から「プロジェクト」を選択する。 「テンプレート」は「Win32プロジェクト」を使う。ここでは「プロジェクト名」は「xxx」とし た。
 プロジェクトの作成で「OK」ボタンを押すと「Win32アプリケーションウイザード」の画面が開く。 ここで「アプリケーションの設定」を開き、「アプリケーションの種類」で「DLL」を選択する。 さらに「空のプロジェクト」にチェックを入れる。



XPCOM用IDLの作成

 VC++の「プロジェクト」メニューの「新しい項目の追加」を選択する。そして「テンプレート」から 「MIDLファイル(.idl)」を選択してファイル名を「Ixxx.idl」としてファイルを作成する。

 新しく作成したIDLファイルには初めから2行あるが、それを削除してファイル内容を以下のようにす る。

#include "nsISupports.idl"

[scriptable, uuid(2E02A2B5-AD6F-4688-A75B-F642838BCCA2)]
interface Ixxx : nsISupports
{
	long	Add(in long nData1, in long nData2);
	AString	AddString(in AString strData,in long nData);
};

※太字で強調している部分はVC++に含まれるGuidGen.exeを使って新しいGUIDを生成して利用 する。同じ値を使いまわしてはいけない!



IDLファイルビルド設定

 Visual C++標準のIDLビルドをキャンセルして、XPCOM用のIDLビルドコマンドを登録する。

 VC++の「ソリューションエクスプローラー」に新しく追加された「Ixxx.idl」を右クリックし、 現れたメニューから「プロパティ」を選択する。そして開いたダイアログの「構成」から「すべて の構成」を選択し、左側のツリーの「全般」にある「ビルドから除外」を「はい」に変更する。そし て「OK」ボタンを押して設定を保存する。


 VC++の「プロジェクト」メニューから「プロパティ」を選択する。そして「構成」から「すべての構成」 を選択する。左側のツリーから「ビルドイベント」の「ビルド前のイベント」を選択する。ここで右側の 「コマンドライン」に「makexpidl.bat $(ProjectDir)Ixxx.idl」を入力して「OK」ボタンを押して保存す る。

※「クラスビュー」を開いた状態でないと「プロジェクト」メニューに「プロパティ」が見つからない。



main.cppファイルの作成

 VC++の「プロジェクト」メニューの「新しい項目の追加」を選択する。そして「テンプレート」から 「C++ファイル(.cpp)」を選択してファイル名を「main.cpp」としてファイルを作成する。

 ここでは暫定的にファイル内容を以下のようにする。

#include "mozilla-config.h"
#include "windows.h"
#include "wchar.h"
#include "nsEmbedString.h"
#include "Ixxx.h"

#pragma	comment(lib,"odbc32.lib")
#pragma	comment(lib,"odbccp32.lib")
#pragma	comment(lib,"nspr4.lib")
#pragma	comment(lib,"plds4.lib")
#pragma	comment(lib,"plc4.lib")
#pragma	comment(lib,"xpcomglue.lib")


#define MY_COMPONENT_CONTRACTID	"@mydomain.com/xxxxxxx/Ixxx;1"
#define MY_COMPONENT_CLASSNAME	"Ixxx XPCOM"
#define MY_COMPONENT_CID		{ 0x5506ca73, 0x8f02, 0x40b9, { 0x87, 0xeb, 0xfa, 0x53, 0xc9, 0x58, 0x70, 0xfc } }

※太字で強調している部分はVC++に含まれるGuidGen.exeを使って新しいGUIDを生成して利用 する。同じ値を使いまわしてはいけない!



main.cppファイル内容の作成

 cppファイル内容の作成には「Ixxx.h」が必要だが、まだこのファイルはどこにもない。「Ixxx.h」を 作成するために一度ビルドをする。「ビルド」メニューから「ソリューションのビルド」しビルドする。 これで自動的に「Ixxx.h」が作成される。

 「main.cpp」に書かれている「#include "Ixxx.h"」の上で右クリックをして現れたメニューから 「ドキュメント "Ixxx.h"を開く」を選択し、ヘッダーファイルを開く。

 自動的に作成された「Ixxx.h」の中には以下のように「#if 0」と「#endif」で囲まれた部分がある。 この部分を選択してmain.cppに追加する。

(...省略...)

#if 0		(この行を含まず下の部分を追加)
/* Use the code below as a template for the implementation class for this interface. */

/* Header file */
class _MYCLASS_ : public Ixxx
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_IXXX

  _MYCLASS_();

private:
  ~_MYCLASS_();

protected:
  /* additional members */
};

/* Implementation file */
NS_IMPL_ISUPPORTS1(_MYCLASS_, Ixxx)

_MYCLASS_::_MYCLASS_()
{
  /* member initializers and constructor code */
}

_MYCLASS_::~_MYCLASS_()
{
  /* destructor code */
}

/* long Add (in long nData1, in long nData2); */
NS_IMETHODIMP _MYCLASS_::Add(PRInt32 nData1, PRInt32 nData2, PRInt32 *_retval)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

/* AString AddString (in AString strData, in long nData); */
NS_IMETHODIMP _MYCLASS_::AddString(const nsAString & strData, PRInt32 nData, nsAString & _retval)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

/* End of implementation class template. */
#endif		(この行を含まず上の部分までを追加)

(...省略...)


 ただし追加したときに以下の太字の部分を変更しておく

/* long Add (in long nData1, in long nData2); */
NS_IMETHODIMP _MYCLASS_::Add(PRInt32 nData1, PRInt32 nData2, PRInt32 *_retval)
{
	*_retval = nData1 + nData2;
	return	NS_OK;
}

/* AString AddString (in AString strData, in long nData); */
NS_IMETHODIMP _MYCLASS_::AddString(const nsAString & strData, PRInt32 nData, nsAString & _retval)
{
	PRUnichar	uchText[128];

	swprintf(uchText,L"%d",nData);
	_retval = uchText;
	_retval += strData;

	return	NS_OK;
}


さらに以下の内容もmain.cppに追加する。

#include "nsIGenericFactory.h"

NS_GENERIC_FACTORY_CONSTRUCTOR(_MYCLASS_)

static nsModuleComponentInfo components[] =
{
	{
		MY_COMPONENT_CLASSNAME, 
		MY_COMPONENT_CID,
		MY_COMPONENT_CONTRACTID,
		_MYCLASS_Constructor,
	}
};

NS_IMPL_NSGETMODULE("_MYCLASS_Module", components) 

※ここまでの処理で完成したmain.cppの内容はこのページ下部に表示してあります。



プロジェクトの設定

 VC++の「プロジェクト」メニューから「プロパティ」を選択する。そして「構成」から「Debug」 を選択する。左側のツリーから「C/C++」の「プリプロセッサ」を選択する。ここで右側の 「プロセッサの定義」に「;XPCOM_GLUE」を追加する(既存の文字列は消さないこと!)。
 同じように「構成」が「Release」のときの「プロセッサの定義」にも追加しておく。

 次に「構成」を「すべての構成」にして「リンカ」の「入力」にある「特定のライブラリの無視」 に「libcmtd.lib」を追加する。

※「クラスビュー」を開いた状態でないと「プロジェクト」メニューに「プロパティ」が見つからない。
※「libcmtd.lib」を除外するという方法はかなり強引で、本来なら避けるべきものだが...今回は簡 便化のためにこうした。除外しない方法は次回以降に紹介する。



XPCOMの生成

 これで「ビルド」メニューから「ソリューションのビルド」を選択してびるどをする。すると以下のファイル を得ることができる。

・xxx.dll
・Ixxx.idl
・Ixxx.xpt

 これら3つのファイルがFirefoxなどで利用するためのXPCOMコンポーネントとなる。




main.cppの内容

 上の説明が分かりずらいのでここまででできたmain.cppの全内容を以下に示す。

#include "mozilla-config.h"
#include "windows.h"
#include "wchar.h"
#include "nsEmbedString.h"
#include "Ixxx.h"

#pragma	comment(lib,"odbc32.lib")
#pragma	comment(lib,"odbccp32.lib")
#pragma	comment(lib,"nspr4.lib")
#pragma	comment(lib,"plds4.lib")
#pragma	comment(lib,"plc4.lib")
#pragma	comment(lib,"xpcomglue.lib")


#define MY_COMPONENT_CONTRACTID	"@mydomain.com/xxxxxxx/Ixxx;1"
#define MY_COMPONENT_CLASSNAME	"Ixxx XPCOM"
#define MY_COMPONENT_CID		{ 0x5506ca73, 0x8f02, 0x40b9, { 0x87, 0xeb, 0xfa, 0x53, 0xc9, 0x58, 0x70, 0xfc } }


/* Header file */
class _MYCLASS_ : public Ixxx
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_IXXX

  _MYCLASS_();

private:
  ~_MYCLASS_();

protected:
  /* additional members */
};

/* Implementation file */
NS_IMPL_ISUPPORTS1(_MYCLASS_, Ixxx)

_MYCLASS_::_MYCLASS_()
{
  /* member initializers and constructor code */
}

_MYCLASS_::~_MYCLASS_()
{
  /* destructor code */
}

/* long Add (in long nData1, in long nData2); */
NS_IMETHODIMP _MYCLASS_::Add(PRInt32 nData1, PRInt32 nData2, PRInt32 *_retval)
{
	*_retval = nData1 + nData2;
	return NS_OK;
}

/* AString AddString (in AString strData, in long nData); */
NS_IMETHODIMP _MYCLASS_::AddString(const nsAString & strData, PRInt32 nData, nsAString & _retval)
{
	PRUnichar	uchText[128];

	swprintf(uchText,L"%d",nData);
	_retval = uchText;
	_retval += strData;

	return NS_OK;
}




#include "nsIGenericFactory.h"

NS_GENERIC_FACTORY_CONSTRUCTOR(_MYCLASS_)

static nsModuleComponentInfo components[] =
{
	{
		MY_COMPONENT_CLASSNAME, 
		MY_COMPONENT_CID,
		MY_COMPONENT_CONTRACTID,
		_MYCLASS_Constructor,
	}
};

NS_IMPL_NSGETMODULE("_MYCLASS_Module", components) 








Copyright (c) 1999-2007 issei. All rights reserved. (運営者情報