前編
System4.0のデバッグ時の変数表示を自作してみた
こんな感じ です。
イメージ的には、VisualStudioのクイックウォッチ+データヒント。
実行には .net framework2.0 が必要です。
DPQuickShow をダウンロード
以下は、注意が必要な箇所などのメモ
後編
System4.0でDebugPlugin (メモ)
メモです。あまり丁寧ではありません。
DebugPluginとは?
Debug実行時に使用可能なPluginです。
具体的には、コンパイル時に生成される「debug.jad」「debug2.jad」が存在している場合に、
DPフォルダに「~.ade」のファイルがDebugPluginとして認識されます。認識されたDebugPluginは、System4.0のメニューに「デバッグプラグイン」として表示されます。
標準では以下の5個のDebugPluginが認識されています。標準認識されるDebugPlugin [ 解析、ログビューア、SACT、文字列、変数 ]
作成方法
DebugPluginは自作することが可能です。
作成するためには、C++が必要となります。[ Sys42SDK_20041224\熟練者向けセット\DLL開発\開発キット\DP ]
に、C++用のヘッダと、サンプルが存在します。IJaffaDebugPlugin を継承したPluginとなるクラスを作成し、
そのインスタンスを、System4.0から呼び出されるCreatePlugin で戻り値として返します。Initは初期化。Openは開くコマンド時、Closeは閉じるコマンド時(?)、
GetNameはSystem4.0のメニューに表示する名前を返します。
少なくとも、ここまでで一度コンパイルし、メニューに登録されることを確認してください。
拡張子をadeにして、DPフォルダにコピーすれば、自動的に認識されます。
ウィンドウ表示
ウィンドウ表示の方法はいろいろあると思いますが、
MFCとCLR(マネージ拡張)について確認しました。MFCを用いる場合は AFX_MANAGE_STATE でマクロをかましてやる必要があります。
CLR(C++/CLI : VC2005)を用いる場合は、
COMの初期化に失敗するので ( =>原因 )
初期化時にマネージコードを一回実行し、直後にCoUninitializeを実行することで解決します。
また、ネイティブコードからマネージコードを実行することになるのでフォームクラスにgcrootを
かぶせてあげる必要があります。
Debug関連のInterface取得
[ Sys42SDK_20041224\熟練者向けセット\DLL開発\マニュアル\IVMDebugの取得方法.txt ] に書いてあります。
うぃんすろうさんのところの、GetSys4IFを用いて、、、< Init関数内 >
pIMainSystem=(IMainSystem*)pIJaffaDebug->GetInterface(&IID_IMainSystem);
pISys40Ini=(ISys40Ini*)pIMainSystem->GetInterface(&IID_ISys40Ini);
char* vmn=pISys40Ini->GetMainVMName();
pIVMDebug=(IVMDebug*)GetSys4IF(pIVMDebug=NULL,vmn,"GetDebugInterface",&IID_IVMDebug);
pIVMDebugPage=(IVMDebugPage2*)GetSys4IF(pIVMDebugPage=NULL,vmn,"GetDebugInterface",&IID_IVMDebugPage2);
pIVMDebugJabFile=(IVMDebugJabFile*)GetSys4IF(pIVMDebugJabFile=NULL,vmn,"GetDebugInterface",&IID_IVMDebugJabFile);
pIVM=(IVM*)GetSys4IF(pIVM=NULL,vmn,"GetInterface",&IID_IVM);IVMGlobalはGetDebugInterfaceで取得できるハズと考えてますが取得できません。
GetInterfaceで取得すると、IVMと同じアドレスが返ってきました。謎です。
IVMDebugPage
ページとは、関数とかの内部の変数群のこと。
グローバル領域、関数内変数、構造体(クラス)、配列、文字列がそれぞれのページとなる。functypeはポインタ(関数番号)が入っている。定数は含まれない。(ページ/変数ともに)
文字列は、ポインタ(ページ番号)が入っている。
構造体もポインタが入っている(ページ番号)
配列も、ポインタ(ページ番号)。Type=-1:NULL
Type=0:グローバル
Type=1:関数
Type=2:文字列
Type=3:配列
Type=4:構造体
関数一個つむごとに1つ増える。関数を消すと、Type=-1
変数の名前を取得するのは、うまいことIVMDebugJabFileとの整合性を取る必要がありそう。
ページの中身は、基本的に4byte区切り。
32bitのInt、32bitのfloat、32bitのポインタ(このポインタは、ページへのポインタ、あるいは関数/構造体番号)ただし、参照変数の場合は、8byte使用する。(格納は4byte+4byteとなる)
この場合、変数名は、"name","<void>" で格納される。
それぞれの内容は、参照先ページポインタ、ページ内の参照先 が入る。
感想
大変でした。いやほんとに。
これだけ足跡残してあれば、同じようなことをやろうとする人は楽ちんですね。
いないと思うけど。
サンプルは、DPQuickShowのを使用してください。