.NET FrameWorkで作成されたDLL を JavaScript で使用する(2)

ほぼ一年近くも経って前回の続き。
・・・結局ダメ。
DLL内のクラスがCOM+用のインターフェースを搭載してないものと、そうでないものが混ざっており、まともに使えなかった。

よって別の方法を試すことにした。
Visual C++ Express Edition 2005 & Platform SDK で、DLLとJavaScriptの橋渡しをする COMのI/Fを実装するラッパーDLLを作成することにした。


結論

今度はうまくいった。
ちゃんとJavaScriptかとCでコーディングされたDLL間でデータのやり取りや関数の呼出が行えるようになった。
ラッパーDLLを介して。


ラッパーDLLの作り方

準備

Visual C++ Express Edition 2005(と.NET Framework 2.0も) と Platform SDK をインストールする。
(この辺のインストール方法の情報は調べればいくらでも見つかるので他のページにお任せ)

手順

1.プロジェクトの作成

「ファイル」→「新規作成」→「プロジェクト」→「CLR]→「クラスライブラリ」
を選択してプロジェクトを作成する。
(※:今回はプロジェクト名を「COM_TestDll」として進める。以降「COM_TestDll」自分でプログラムを作成する際に自分で決定した文字列に置き換える)

2.プロジェクトの設定

1) 「ソリューション構成」(画面上部の右向き三角のアイコンの右隣のコンボボックス)を「Debug」→「Relese」に変更する
2) ソリューションエクスプローラの「COM_TestDll」を右クリックし、プロパティ」を選択する。
  すると「COM_TestDllプロパティ ページ」ダイアログボックスが開く
3) 「共通プロパティ-参照設定」を選択
4) 「新しい参照の追加」ボタンを押す
5) 「.NET」タブの「System.EnterpriseServices」を選択してOKボタンを押す。

3.キーファイルの設定(厳密なアセンブリ名の署名)

引き続き「COM_TestDllプロパティ ページ」ダイアログボックス内での設定。
1) 「構成プロパティ-リンカ-詳細」を選択
2) キーファイルにキーファイル名を入力(今回はCOM_TestDll.snkとする)
  文字列:

$(ProjectDir)COM_TestDll.snk

3) 「OK」ボタンを押し、ダイアログボックスを閉じる

4.プログラムの作成

4.1.AssemblyInfo.cppの編集
  AssemblyInfo.cppを以下のように書き換える
  変更前:

[assembly:ComVisible(false)];

  変更後:

[assembly:ComVisible(ture)];

  に書き換える

4.2.COM_TestDll.cppの編集
1) ServicedComponentクラス使用のための宣言追加
  コード

using namespace System;

  の次の行に以下の3行を追加

using namespace System::EnterpriseServices;
[assembly:ApplicationName("COM_TestDll")];
[assembly:ApplicationActivation(ActivationOption::Library)];

2) クラスの作成
  デフォルトで「Class1」が設定されているので自分で好きなように書き換える。
  ※今回のプロジェクトでは「TestClass1」「TestClass2」とする。また、クラスは自分で好きに増やして良い)
3) ServicedComponentから先ほどのクラスを派生させる。
  先ほどのクラス名の後ろに

: ServicedComponent

  を付加する
  例)

public ref class TestClass1 : ServicedComponent

4) コンストラクタの作成
  クラス内にクラスメイト同じ名前の戻り値と引数なしの関数をpublicで追加する
  例)

public:
TestClass1(void) { return; };

5) メンバの列挙
  処理したい、変数や関数を列挙する
  (※注意:COMに公開する条件として、メンバは全てpublicでなければならない)

5.キーファイルの作成

  Visual C++ 2005 Express Editionインストールフォルダ内の「SDK\v2.0\Bin\sn.exe」を使用して

sn.exe -k COM_TestDll.snk

  とタイプし、キーファイルを作成する。
  その後、ソースファイルがあるフォルダへキーファイルを移動させる

6.コンパイルの実行

  ソリューションエクスプローラの「COM_TestDll」を右クリックし、「ビルド」を選択する。
  =>エラーとWarningが0件ならば成功

7.レジストリへの登録

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\RegSvcs.exe COM_TestDll.Dll

  (「v2.以降の"."と数字の組み合わせはインストールした.NET Framework 2.0のバージョンによりかわる)
  とタイプし、
  「インストールされたアセンブリ :」(以下省略)
  と、Dllがインストールされれば成功
  (※:アンインストールするには /u オプションをつけて同じコマンドを再度実行すればOK)

今後の課題など

Cで作成したDLL内の構造体やクラスは.NETで作成された構造体と互換性が無く、直接COMに渡すことができない。
要するに、intやlong型などは直接JavaScriptとやり取りできるが、構造体の場合はそのメンバおのおのにアクセスするためには、それぞれインターフェース関数を作る必要がある。
・・・と思う(ひょっとしたらうまい方法があるのかも知らないが現在自分は知らない。)
よって、Cで作成したDLLのクラスが持つメンバ(また、そのメンバが持つメンバも含む)が多いと、その分インターフェース関数を用意するのがめんどくさい。
そこをもうちょっと何とかならないかと考えている。