夕暮ログ

C#やJavascript、最近はAndroidなんかも好きなtinqのブログ。「夕暮れログ」

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

【ビジュアライザ】プロクシクラスから置き換える

前回の記事の続きです。
ビジュアライザでシリアライズできないクラスもプロクシクラスを通すことでビジュアライザに渡せると説明しました。
今回は、ビジュアライザで編集した結果をVisualStudioのほうに戻します。
通常、ReplaceObjectを使って戻します。しかし、プロクシクラスを通す場合、そのままではできません。
プロクシクラスはあくまでプロクシクラスで、元の型に自動で変換してくれるわけではないからです。
オブジェクトソースの側で処理を行い、もとの型を取り出して返す必要があります。
現在はGetDataだけのProxyVisualizerObjectSourceクラスに以下のコードを追加します。
public override object CreateReplacementObject(object target, Stream incomingData)
{
    BinaryFormatter bf = new BinaryFormatter();
    ProxyMessage pm = (ProxyMessage)bf.Deserialize( incomingData );
    return pm.GetMessage();
}
CreateReplacementObjectは、ReplaceObjectやReplaceDataが内部で呼び出す関数です。
targetは、どうやら元のオブジェクトが渡されるようです。
incomingDataは、シリアライズされた変更後のオブジェクトが渡されます。
このクラスでは、ProxyMessageが渡されます。
それをGetMessageでもともとのデバッグする型である、Messageに直してreturnします。
詳しくは、MSDNの「VisualizerObjectSource.CreateReplacementObject メソッド」をご覧ください

Showのコードはこのように直します。
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
{
    Message m = ((ProxyMessage)objectProvider.GetObject()).GetMessage();
    MessageBox.Show(m.ToString());
    var test = new Message();
    test.Msg = 10;
    objectProvider.ReplaceObject(new ProxyMessage(test));
}
あたらしいtestという変数を作り、違いがわかるようにMsgに適当な値を設定します。
そして、ここがポイントです。
ReplaceObjectで返すのはMessageではなく、ProxyMessageです。
これが内部でシリアライズされ、先ほど作ったCreateReplacementObjectメソッドに渡されます。
そして、そのCreateReplacementObjectメソッドが再び逆シリアル化し、ProxyMessageをとりだします。
そのProxyMessageからもとのMessageを取り出し、最後にreturnすることで、デバッガに変更後のオブジェクトが戻るのです。

TestShowVisualizerをよんでテストすると、うまく言っていることがわかると思います。
しかし、いざ使おうとすると、エラーがでてしまうようです。
私の環境の場合、実際にVisualStudioから使うと、
[A]ClassLibrary1.ProxyMessage は [B]ClassLibrary1.ProxyMessage. 型 A は 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' (コンテキスト'Default'、位置 'C:\Documents and Settings\UserName\My Documents\Visual Studio 2008\Projects\C#Projects\Temp\ClassLibrary1\DebuggerTester\bin\Debug\ClassLibrary1.dll') から生成されます. 型 B は 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' (コンテキスト'LoadFrom'、位置 'C:\Documents and Settings\UserName\My Documents\Visual Studio 2008\Visualizers\ClassLibrary1.dll') から生成されます にキャストできません。 という、むだに長い例外がでます。本当に何が言いたいのかわかりにくいですが、よくよく見ると、DLLのパスが違います。
そう、デバッグ用に参照の追加で指定を行っている場合、途中の経路で別のDLLの型を使ってしまうようです。
仕方が無いので、もうひとつ別のウィンドウでビジュアルスタジオを開き、そちらで確認を行うか、テスト用クラスからそのライブラリへの参照設定を解除してください。

これで試せばうまくいくはずです。
ただし、TestShowVisualizerを呼び出している箇所はエラーになるので、コメントアウトしておいてください。
マウスを重ねると、ちゃんと表示されます。

ココでは空のMessageを渡したので、空のデータが表示。値を設定してもちゃんと渡せていることがわかります

ビジュアライザでの変更。ちゃんと適用されています。


これで、シリアライズできないクラス・構造体をデバッグするは終わりです。
のちほど、サンプルにまとめてサイトにアップする予定です。やっぱめんどくさいのでパス^^;どうしても必要な場合、コメントへお願いします。アップします。


ちなみに、この置き換える関数では時間をかけてはいけません。
時間がかかると、「関数の評価がタイムアウトしました。。」と出て変更が失われます。
大体1秒(1000ms)が目安のようです。なのでここでは最低限の作業のみを行いましょう。
メッセージボックスを表示させようものならすぐに時間を使い果たしてしまうため、そのようなことは避けてください。
それでも時間がかかる処理がある場合、デバッグソースではなくデバッガビジュアライザの側で、ReplaceObjectを呼ぶ前に必要な処理を行わせるのがいいと思われます。
関連記事

コメント

ここをクリックしてコメントを投稿

非公開コメント

トラックバック

http://tinqwill.blog59.fc2.com/tb.php/41-395387bf

« next  ホーム  prev »

プロフィール

tinq tinq(もしくはTinqWill)

Sky  For   Every 改装予定

プログラミングお勉強中の高校生。月一くらいは更新したい

最新記事

カテゴリ

月別アーカイブ

検索フォーム

最新コメント

リンク

最新トラックバック

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。