今回の趣旨
前回に引き続き、rFactor2のプラグイン例(Jan 15, 2012版)について解析をする。
必要な知識は、DLL及びC++となる。
DLLの定義
rFactor2では、プラグイン=DLLである。
最低限、決められた関数のエクスポート定義をしてやれば、とりあえずのプラグインを作成できることを意味する。
MODやプラグインがユーザーに作られることを前提にしている。
そのため、開発者としてユーザーに対して、フレンドリーであるといえる。
Example.cppに書かれているエクスポート定義(DLLを読み込む側への関数の宣言)は、下記の通り。
・プラグインの名前を返す関数
まだ、筆者のrFactor2での調査が足りないだけかもしれないが、MOD名をrFactor2本体から
取得できる前提としているようだ。
extern “C” __declspec( dllexport )const char * __cdecl GetPluginName() { return( “ExamplePlugin – 2008.02.13” ); }
・プラグイン種別を返す関数
プラグインの種別(定数で定義されている)を返す。プラグインの種別については後述。
extern “C” __declspec( dllexport )
PluginObjectType __cdecl GetPluginType() { return( PO_INTERNALS ); }
・プラグインのバージョンを返す関数
書いてある通りではないか?と思うかもしれない。
だが関数はintで返すので、1.1であろうが2.5であろうが、キャストされて整数だけが返される。
プラグインの中では、1000倍の値を返しましょうと書かれているので、バージョン1.0なら1000を返すのが、
rFactor2での約束事となる。
逆に、rFactor2.exeからプラグインには、1000倍の値で来るので、1000で割って、
小数点で表示するサンプルがある。
extern “C” __declspec( dllexport )
int __cdecl GetPluginVersion() { return( 1 ); } // InternalsPluginV01 functionality
・プラグインオブジェクトの参照を返す関数
後述するクラス体系に基づいたrFactor2からのプラグイン呼び出しが行われると推測される。
最上位クラスとなるPluginObjectのメンバ関数定義は、決まっているので作成できるプラグインの幅は、
これに縛られると考えられる。
extern “C” __declspec( dllexport )
PluginObject * __cdecl CreatePluginObject() { return( (PluginObject *) new ExampleInternalsPlugin ); }
・プラグインオブジェクト破壊関数
プラグイン終了時に、プラグイン・クラスのオブジェクトを消滅させる関数。お約束。
extern “C” __declspec( dllexport )
void __cdecl DestroyPluginObject( PluginObject *obj ) { delete( (ExampleInternalsPlugin *) obj ); }
PluginObjectの概要
全てのプラグインオブジェクトは、PluginObjectクラスを継承したクラスとなる。
よって、PluginObjectクラスを理解することがスタート地点となる。
関数はたった2つ。変数は1つである。その他、5つの型定義となっている。
PluginObjectの関連型定義
見たままなので、省略する。
typedef const char * ( __cdecl *GETPLUGINNAME )();
typedef PluginObjectType ( __cdecl *GETPLUGINTYPE )();
typedef int ( __cdecl *GETPLUGINVERSION )();
typedef PluginObject * ( __cdecl *CREATEPLUGINOBJECT )();
typedef void ( __cdecl *DESTROYPLUGINOBJECT )( PluginObject *obj );
PluginObjectの関連型定義
プラグインの種別は、列挙方で定義されている。
実質、0~4の5つの種類のプラグインを作成できる。”GAMESTATS”は、 統計情報(statistics)用?
”INTERINTERNALS”は、今回のサンプルで使われているもの。走行データ等を取りたいときは、
この”INTERNALS”を使用することになる。また”RFONLINE”は、オンライン用のプラグインと考えられる。
現時点で詳細は不明だが、XFireやTeam Speak3等のゲーム用メッセンジャー等と連携してボイスチャット等のプラグインが作れるかもしれない。(憶測)
”NCPLUGIN”は、NCが何の略か不明。”IVIBE”も同様に不明。
※PO_は、プラグインオブジェクトの接頭文字。
enum PluginObjectType
{
PO_INVALID = -1,
//---------------—-
PO_GAMESTATS = 0,
PO_NCPLUGIN = 1,
PO_IVIBE = 2,
PO_INTERNALS = 3,
PO_RFONLINE = 4,
//---------------—-
PO_MAXIMUM
};
次回
次回は、プラグイン種別で定義されている5つの形式のうち、PO_INTERNALS形式。
すなわち、InternalsPluginクラスについて解析を行う予定。
※その他、プラグイン形式のサンプル・定義ファイルは、まだ公開されていないようだ。