一体俺は何をやっているんだ...
1. 環境
1.1. .Net Framework
- Visual Studio 2017
- C#
- Windows 10 (summer) Creators Update (bootcamp)
1.2. VB6
- VB6 Enterprise (SP6, SP6B適用)
- Windows 10 (summer) Creators Update (bootcamp)
2. DLL側の準備
MSのドキュメントを参照すると、DLL側でCOM相互参照機能から利用できるようにするために以下のような準備が必要。
- クラスはパブリックであること。
- プロパティ、メソッド、およびイベントがパブリックであること。
- プロパティとメソッドがクラス インターフェイスで宣言されていること。
- イベントがイベント インターフェイスで宣言されていること。
パブリックであることはCOM相互参照機能でなくても必要なので、インターフェイスの宣言が必要になる。
その際には、System.Runtime.InteropServices
名前空間のCOM参照用の属性を宣言する必要がある。
簡単な MyMath
クラスを作成してCOM相互参照可能に修正してみる。
次のようなクラスだ。
namespace MyClassLibrary
{
public class MyMath {
public int Add(int a, int b) {
return a + b;
}
}
}
これを次のように修正する。
using System.Runtime.InteropServices;
namespace MyClassLibrary
{
public interface IMyMath
{
int Add(int a, int b);
}
[ClassInterface(ClassInterfaceType.None)]
public class MyMath : IMyMath
{
public int Add(int a, int b)
{
return a + b;
}
}
}
参考のドキュメントでは Guid
アトリビュートを利用しているが、明示指定する必要はなさそうだ。
2017/10/10 追記
GuidアトリビュートはCOMに登録する際のIDになるらしく、Guidアトリビュートを指定しないと、DLLを更新してCOMへのアセンブリ登録を再度行った際に、前回登録したアセンブリが特定できずに更新できないエラーとなる模様。
その際のエラーメッセージは次のようなもの
COM 相互運用機能に対して登録解除できる型を含んでいません。
ソースの他にVisual Studioのソリューションエクスプローラからプロジェクトの Property
ファイルを編集する。
- [アプリケーション]タブ > [アセンブリ情報] > [アセンブリをCOM参照可能にする] に チェック
- [ビルド]タブ > [COM相互運用機能の登録] に チェック
管理者権限で Visual Studio 2017 を起動し Release ビルドすると、プロジェクトフォルダの bin/Release
に3つのファイルが確認できる。
- MyClassLibrary.dll
- MyClassLibrary.tlb
- MyClassLibrary.pdb
また、Visual Studio がビルドの過程で COMへのアセンブリ登録 を済ませてくれている模様。
これで、DLL側の準備は完了。
3. 呼び出し側VB6の作業
DLLでビルドしたPCと別PCでおこなう場合には COMへのアセンブリ登録 が必要になる。
Visual Basic を起動し、空プロジェクトを作成したあと、メニューから [プロジェクト] > [参照設定] を選択する。
参照可能なライブラリファイルの中に登録した dll
があるのでチェックを付けて[OK]を選択する。
ない場合は、[参照]ボタンを選択して MyClassLibrary.tlb
を選択して追加し、チェックを付ける。
これで呼び出し側の設定も完了。
4. VB6で呼び出し実装
次のようなコードを書いて、DLLを利用してみる。
Private Sub Form_Load()
Dim MyMath As MyClassLibrary.MyMath
Set MyMath = New MyClassLibrary.MyMath
Label1.Caption = MyMath.Add(1, 2)
End Sub
参照設定に登録してあると補完機能が利用できる。
引数の型も変換されている。
.Net Frameworkのintは32bitなのでVB6ではlongになる。
実行結果は以下のようになる。