Chapter.25

アクティブスクリプト


1.アクティブスクリプト

どの時代からアクティブスクリプトと呼ぶようになったのかは知りませんが、Windowsにはアプリケーションに組み込み可能なスクリプトエンジンがあります。そして、このスクリプトエンジンはCOMとして実装されています。(と言うか、このサイトを見に来ると思われる人々にはこういう基礎的な解説は不要だな・・・。)

アクティブスクリプトの基礎となるインターフェースはIActiveScriptIActiveScriptSiteの2つです。OLEで実装されている多くのインターフェースと同じように、末尾にSiteと名前の付いたインターフェースはクライアントが実装しなければならないインターフェースです。スクリプトエンジンは必要に応じてクライアントのIActiveScriptSiteを呼び出してスクリプトを処理します。必要なインターフェースは他にもありますが、とりあえずこの2つを押さえておけば問題ないので、サンプルを提示します。

VB.NETサンプルソース:chap25.vb.lzh (35KB 2007/7/22)
C#サンプルソース:chap25.cs.lzh (35KB 2007/7/22)


2.Marshal.GetIDispatchForObject

スクリプトはそれ自身では何もすることはできません。スクリプトが操作するべきオブジェクトをクライアントから供給する必要があります。今回のサンプルはキーワード"this"によってFormにアクセスできるように作りました。スクリプトエンジンにオブジェクトを供給するために使用するのが、IActiveScript.AddNamedItemIActiveScriptSite.GetItemInfoです。これだけなら話は簡単なのですが・・・。

スクリプトエンジンにオブジェクトを供給するIActiveScriptSite.GetItemInfoメソッドはIUnknownITypeInfoのインターフェースポインタを受け取るためにインターフェースポインタへのポインタをパラメータとして持っています。このインターフェースポインタへのポインタにはスクリプトエンジン側からNULLを指定することが可能です。インターフェースのマネージ定義でこれらをout(VB.NETではByRef)パラメータとして定義した場合、スクリプトエンジンからNULLを渡されるとNULLポインタに書き込むを行うためにSystem.ExecutionEngineException例外が発生します。この問題に対処するためには、ポインタにNULLが渡されたかどうかをチェックできるようにマネージ定義でIntPtrを使用する必要があります。IntPtrにインターフェースポインタを返すためには、オブジェクトのCCWをIntPtrとして取得しなければなりません。これを行うために使用するのがMarshal.GetIDispatchForObjectメソッドです。

Marshal.GetIDispatchForObjectメソッドでCCWを取得するためには、クラスをpublicとして宣言しなければなりません。これはRegAsm.exe等を使用してアセンブリを相互運用機能へ公開する時も同じです。サンプルを作成した時には、これに気づいておらず、ちょっと苦労しました。


3.まとめ

CCWでポインタへのポインタを扱うのがちょっと厄介であることが分かっていただければ幸いです。RCWでポインタへのポインタはOleUIInsertObjectで扱いましたが、あの時は詳細に解説するのを失念していました。(ま、ええか・・・。)
他にもいろいろとポイントがありますが、サンプルとMSDNを見てください。

道草を食うのも2回目です。3回までやれば元々の道を忘れてしまいそうですが、そろそろ本筋に戻りたいと思います。


前へ 次へ
OLE on .NET Frameworkへ
総合トップへ

サンプルで使用しているキーワード
IActiveScript IActiveScriptError IActiveScriptParse IActiveScriptSite IActiveScriptSiteWindow System.Activator.CreateInstance System.Runtime.InteropServices.EXCEPINFO System.Runtime.InteropServices.Marshal.BindToMoniker System.Runtime.InteropServices.Marshal.GetIDispatchForObject System.Type.GetTypeFromProgID