C++でGoogle Chromeのプラグインを書いてみた
はじめに
Google Chromeでプラグインを書くには、NPAPIを使用する必要があるあるけど、サンプルプログラムが少ないから勉強するのに敷居が高い。そこで、Nixysaを使うと簡単にプラグインを作成できる。
今回作ったコード
https://github.com/nus/NPAPISample
参考にしたサイト
http://code.google.com/p/nixysa/wiki/HelloWorldWalkThru
Nixysaとは
C++のコードからNPAPIを生成させるツール。
http://code.google.com/p/nixysa/
NPAPIで出来ること
- OSのAPIやシステムコールが呼び出せる。
- C/C++でブラウザを拡張
- NPAPIプラグインをJavascriptで呼び出せる
- Google ChromeやFirefoxで動作する。
開発環境
- Nixysa (NPAPIのラップライブラリ)
- Subversion or TortoiseSVN (Nixysaのコード取得用)
- Python (Nixysaを動作させるため)
- Visual C++ 2010 (プラグインのビルド)
- Google Chrome 9
サンプルプラグインの動作
四則演算を行うプラグインを作る。
C++のコードに起こすとこんな感じ。
class Calcurator { float add(float a, float b) {return a + b;} float sub(float a, float b) {return a - b;} float mul(float a, float b) {return a * b;} float div(float a, float b) {return a / b;} };
これをNixysaでNPAPIのコードを生成させる。
開発の流れ
- Nixysaのダウンロード
- Nixysaに必要なファイルを書く
- Visual C++でプロジェクトファイルの作成
- NixysaでNPAPIのソースコードを生成
- 生成されたファイルをプロジェクトに追加しビルド
- Google Chromeにプラグインをインストール
1.Nixysaのダウンロード
svn checkout http://nixysa.googlecode.com/svn/trunk/ nixysa-read-only
作業フォルダをnixysa-read-onlyとする
2.クラスを書く
nixysa-read-only ├─NPAPISample calculator.cc calculator.h calculator.idl calculatorplugin.cc
宣言
https://github.com/nus/NPAPISample/blob/master/calculator.h
定義
https://github.com/nus/NPAPISample/blob/master/calculator.cc
クラスの構成をIDLファイルで書く
https://github.com/nus/NPAPISample/blob/master/calculator.idl
プラグインの概要を書く
https://github.com/nus/NPAPISample/blob/master/calculatorplugin.cc
3.Visual C++でプロジェクトファイルの作成
メニューバー -> ファイル -> 新規作成 -> 既存のコードからのプロジェクトを作成
既存のコードからのプロジェクトを作成ダイアログが出る
[次へ]
「プロジェクトファイルの場所」はコードの作成場所を指定
「プロジェクト名」をここでは、calculatorとした。
「プロジェクトの種類」を[ダイナミックリンクライブラリ(DLL)プロジェクト]を指定
[次へ]
「プリプロセッサの定義」に「OS_WINDOWS」を追加
[次へ]
[完了]
calculatorプロジェクトのプロパティで[構成プロパテ] -> [C/C++] -> [全般]の「追加のインクルードディレクトリ」に
.;..\nixysa\static_glue\npapi;.\glue;..\third_party\npapi\include;%(AdditionalIncludeDirectories)
と入力
[OK]
4.NixysaでNPAPIのソースコードを生成
calculator.idlのプロパティで「項目の種類」を「カスタム ビルドツール」に変更
[OK]を押し、再度、calculator.idlのプロパティを開く
[構成プロパティ] -> [カスタム ビルドツール] の「コマンドライン」に
$(ProjectDir)\..\nixysa\codegen.bat --output-dir=glue --generate=npapi --force %(Filename)%(Extension)
「出力ファイル」に
glue\%(Filename)_glue.cc;glue\%(Filename)_glue.h;glue\globals_glue.cc;glue\globals_glue.h;glue\hash;%(Outputs)
を書く
calculator.idlのみコンパイル
すると、nixysa-read-only\NPAPISample\glueフォルダにソースコードが生成される。これが、NixysaでNPAPIのコードを出力したもの
5.生成されたファイルをプロジェクトに追加しビルド
プロジェクトにファイルを追加
nixysa-read-only\NPAPISample\glue\ +calculator_glue.cc calculator_glue.h globals_glue.cc globals_glue.h nixysa-read-only\nixysa\static_glue\npapi +common.cc main.cc npn_api.h static_object.cc common.h npn_api.cc plugin_main.h static_object.h
nixysa-read-only\examples\complexフォルダの
complex.rc complex.def
をnixysa-read-only\NPAPISampleにコピーし、この2うつのファイル名を
calculator.rc calculator.def
に変更する。
次に中身を編集
calculator.rcファイルの70行目に
VALUE "FileExtents", ""
を追加
プラグイン名に合わせて他の行も編集
編集し終えたファイル
https://github.com/nus/NPAPISample/blob/master/calculator.def
https://github.com/nus/NPAPISample/blob/master/calculator.rc
プロジェクトファイルのプロパティで[構成プロパティ] -> [リンカー] -> [入力] の「モジュール定義ファイル」の欄に
「calculator.def」を入力
6.生成されたファイルをプロジェクトに追加しビルド
プロジェクトのビルドをすると、calculator.dllが生成される。
これが、プラグイン
6.1 ビルドエラーの対処方法
もし、下記の様なビルドエラーが起きたら
1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C2146: 構文エラー : ';' が、識別子 'ContextRecord' の前に必要です。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12983): error C2065: 'PCONTEXT' : 定義されていない識別子です。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2146: 構文エラー : ')' が、識別子 'ContextRecord' の前に必要です。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): warning C4229: 旧形式が使用されています : データの修飾子は無視されます。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2182: 'RtlCaptureContext' : 'void' 型が不適切に使用されています。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2491: 'RtlCaptureContext' : dllimport データ の定義は許されません。 1>C:\Program Files\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2059: 構文エラー : ')' 以下同様なエラー ...
nixysa-read-only\third_party\npapi\include\nptypes.hの48行目に1行追加
47 #if defined(WIN32) || defined(OS2) 48 #include <Windows.h> // この行を追加
nixysa-read-only\nixysa\static_glue\npapi\npn_api.hの107,108行目の
107 size_t size = std::min(sizeof(g_browser_functions), 108 static_cast<size_t>(funcs->size));
を
107 size_t size; 108 { 109 using namespace std; 110 size = min(sizeof(g_browser_functions), 111 static_cast<size_t>(funcs->size)); 112 };
に変更
終りに
以上がプラグインの製作過程
後は、Google ChromeなりFirefoxの拡張機能の作り方に従い、プラグインを読み込ませる。