SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

COM相互運用機能の利用

COMに公開できる.NETコンポーネントの設計

  • X ポスト
  • このエントリーをはてなブックマークに追加

.NETまでもう少し

 ここまでくれば、.NETコードに近づいてきました。COMに公開可能な.NETコンポーネントの作成に進むには、まず、こうした概念をよく理解しておくことが重要です。家を建てる前に必要な設計図のようなものと考えてください。設計図なしでも進めることは可能ですが、正しく始めた方が良い家になります。

 VB6でCOMオブジェクトを作成する際に内部でどのような処理が行われているか、簡単に復習します。

  • COMはインターフェイスに基づいています。COM内のすべてがインターフェイスを介して呼び出されます。
  • VB6では、COMクラスを作成するときに開発者がインターフェイスを直接実装することはできません。VB6が開発者の代わりにインターフェイスを作成してくれます。作成されるインターフェイスは、クラス名の前にアンダースコア(_)を付けた名前になります。
  • VB6で作成されたインターフェイスは、常にデフォルトCOMインターフェイスとして指定されるので、スクリプティングクライアントにはこのインターフェイスのメソッドのみが公開されます(上記の例の場合、RobotオブジェクトのIMaidのメソッドはVBScriptからは使えません)。

メソッドはどこに消えた!?

 多くの人は、初めて.NETオブジェクトをCOMに公開してそのオブジェクトをVB6から使おうとしたときに、メソッドが1つもないと驚きます。COMに公開する簡単な.NETクラスライブラリを作成して、なぜそうなるのか見ていきましょう。

VB.NETの場合
Option Strict On
Option Explicit On

Namespace QuickNET
    Public Class Bee
        Public Sub FindFlowers()

        End Sub

        Public Sub MakeHoney()

        End Sub
    End Class
End Namespace
C#の場合
using System;

namespace QuickNET
{
    public class Bee
    {
        public void FindFlowers()
        {
        }

        public void MakeHoney()
        {
        }
    }
}

 この.NETコンポーネントからCOMタイプライブラリを作成し、どのようになるか見てみます(この段階では、COMタイプライブラリを作成するだけでCOM用の登録は行いません)。Visual Studio .NETコマンドプロンプト([スタート]→[すべてのプログラム]→[Microsoft Visual Studio .NET]→[Visual Studio .NET Tools]→[Microsoft Visual Studio.NET Command Prompt])を開き、上記をコンパイルした.NETコンポーネントのディレクトリに移動し、以下のコマンドを入力します。

TLBEXP.EXE QuickNET.dll /out:Com.QuickNET.tlb

 「TLBEXP.EXE」ユーティリティは、.NETアセンブリからCOMタイプライブラリを生成します。生成されるタイプライブラリには任意の名前を付けることができますが、通常は慣例的ルールに従って.tlb拡張子を付けます。また、私はCOMに公開するタイプライブラリの名前の先頭に「Com.」と付けることにしています。次に、OLE Viewで「Com.QuickNET.tlb」というタイプライブラリを開きます。以下に重要な部分を抜粋します。

coclass Bee {
    [default] interface _Bee;
    interface _Object;
};

interface _Bee : IDispatch {
};

 これは、VB6のCOMタイプライブラリとよく似ています。Beeクラスに_Beeというインターフェイスが作成されており、これがデフォルトインターフェイスになっています。ただし、このインターフェイスにはメソッドが1つもありません。VB6を起動してプロジェクトにこのタイプライブラリへの参照を追加し、オブジェクトブラウザで確認しても、Beeクラスにメソッドはありません(VB6は常に、デフォルトインターフェイスからそのクラスのメソッドを探します)。

 この記事の説明においては、_Objectインターフェイスは重要ではありません。あらゆるクラスの継承元となる.NETのObjectクラスは_Objectインターフェイスを公開しているので、エクスポートされた型すべてに_Objectインターフェイスが追加されます。

 TLBEXP.EXEユーティリティで_Beeインターフェイスにすべてのメソッドが追加されなかったのはなぜでしょうか。COMインターフェイスのレイアウトはバインディングコントラクトなので、.NETクラスに新しいメソッドを追加してCOMタイプライブラリを生成し直すとレイアウトが変わる場合があり、前のレイアウトに基づいてコンパイルした既存のCOMクライアントが動作しなくなることがあります。空のインターフェイスを定義することによって、すべてのクライアントが遅延バインディング呼び出しを行うことになり、新しいバージョンの.NETコンポーネント(およびそのコンポーネント用のCOMラッパー )も、COMクライアントをコンパイルし直さなくても、正しく動作します。

各種の制御

 それでは、VB6で.NETコンポーネントのこれらのメソッドを表示するにはどうすればよいのでしょうか。VB6とCOMについて言えることを、.NETにも適用できます。基本的に、必要な操作は以下の2つです。

  • 作成したメソッドを定義するインターフェイスを作成する。
  • そのインターフェイスをデフォルトインターフェイスにする。

 1番目は簡単です。COMに公開したいメソッドを含む.NETインターフェイスを追加します。

VB.NETの場合
Public Interface IBee
    Sub FindFlower()
    Sub MakeHoney()
End Interface
C#の場合
public interface IBee
{
    void FindFlower();
    void MakeHoney();
}

 次にこのインターフェイスをBeeクラスに実装します。

VB.NETの場合
Public Class Bee
    Implements IBee

    Public Sub FindFlower() Implements IBee.FindFlower
    End Sub

    Public Sub MakeHoney() Implements IBee.MakeHoney
    End Sub
End Class
C#の場合
public class Bee : IBee
{
    public void FindFlower()
    {
    }

    public void MakeHoney()
    {
    }
}

 このコンポーネントをコンパイルし、TLBEXP.EXEユーティリティを実行し、OLE Viewで確認します。結果は意外かもしれません。

interface IBee : IDispatch {
    ...
    HRESULT FindFlower();
    ...
    HRESULT MakeHoney();
};

coclass Bee {
    [default] interface _Bee;
    interface _Object;
    interface IBee;
};

interface _Bee : IDispatch {
};

 標準COMインターフェイスとして、IBeeインターフェイスが現れました。しかも、そこにメソッドが含まれています。さらに、Beeコクラスにこのクラスが実装されています(これは予想どおり)。しかし、まだ(空の)_Beeインターフェイスがデフォルトインターフェイスに指定されたままになっています。VB6がクラスのメソッドを探すのは、やはりこのデフォルトインターフェイスです。

 それでも、IBeeインターフェイスは標準COMインターフェイスとして公開されているので、このインターフェイスを介して必要な操作を問題なく実行できます。例えば、上記で作成したタイプライブラリを使う以下のVB6コードは正しく実行できます。

Dim bee As IBee
Set bee = New Bee
bee.FindFlower
bee.MakeHoney

 しかしながら、もっときちんと統合するには、IBeeインターフェイスをデフォルトインターフェイスにする必要があります。これは、属性を使って行います。

次のページ
属性

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Patrick Steele(Patrick Steele)

ミシガン南東部で独立コンサルタントとして活動。ASP.NET、WinForms、COM+、COM相互運用機能など.NETの広範な経験を持つ。ミシガン五大湖地域の.NETユーザーグループ(GANG - http://www.migang.org)の主事でもあり、過去5年にわたりMicrosoft社の.NET ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/429 2006/08/22 15:50

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング