2012-04-10 11 views
6

私は、クラスObjectがJavaのようにObject Orientedプログラミング言語のクラスhiearchyの最上位にあることを理解しています。また、.NETに参照型と値型があることも理解しています。私はC言語の型定義も理解しています。VB6オブジェクトとデータ型

これにもかかわらず、私はオブジェクトがVB6( http://msdn.microsoft.com/en-us/library/aa338034%28v=vs.60%29.aspx )にあるのか、またその変種とは何かを理解するのには苦労しています。バリアントとは何ですか? VB6でオブジェクトがどのように実装されていますか?

+0

VB6バリアントには、http://msdn.microsoft.com/en-us/library/aa908601.aspxで説明されている構造が含まれています。 – Bob77

答えて

9

VB6で使用されるすべてのオブジェクトはCOMオブジェクトです。 COMオブジェクトは本質的に可変長データ構造であり、その可変長ヘッダにはVTableへの32ビットポインタの数が任意に含まれ、連続するバイトにはオブジェクトのインスタンスデータが含まれます。

Bytes 
0-3 VTable1 pointer 
4-7 VTable2 pointer 
8-11 VTable3 pointer 
... 
     Instance data 

VTableは、すべて "this"インスタンスポインタが渡される関数に対する32ビットポインタの配列です。

Bytes 
0-3 Func1(this, ..., ...) 
4-7 Func2(this, ..., ...) 
8-11 Func3(this, ..., ...) 
... 

唯一の他の仕様は、そのすべてのvtable MUST継承のIUnknownから、すなわち最初の3つの関数がある必要があります

QueryInterface() 
AddRef() 
Release() 

基本的に、QueryInterfaceが()を使用すると、COMオブジェクトが(UUIDによって表される)特定のインターフェイスをサポートしているかどうかを確認することができます。 AddRef()は、オブジェクトライターが内部参照カウントをインクリメントできるようにします。 Release()を使用すると、オブジェクトライターは参照カウンタを減らし、カウントがゼロのときにオブジェクトを破棄できます。 VBでこれらのメソッドを呼び出すことは決してありません - コンパイラはこれらの呼び出しをあなたに追加します(VB6の利点の1つ)。

詳細はhttp://msdn.microsoft.com/en-us/library/windows/desktop/ms680509(v=vs.85).aspxを参照してください。

VBオブジェクトタイプは、IDispatchインターフェイスをサポートするオブジェクト(http://msdn.microsoft.com/en-us/library/windows/desktop/dd318520(v=vs.85).aspxを参照)への参照です。これは、VBおよびVBScriptでレイトバインディングを実行できるようにするものです。 VB6で記述されたすべてのオブジェクトは、IDispatchから継承するインターフェイスを自動的に実装します。これは、初期および後期バインドをサポートするため、デュアルインターフェイスと呼ばれます。

COMに直接型システムが組み込まれていないことに注意してください。ただし、オブジェクトのユーザーがオブジェクトについて追加する情報にアクセスできるようにするITypeInfoインターフェイスをサポートすることができます(この情報を格納するために型ライブラリを使用する既定の実装を使用する方が簡単です)。

Variant型は、実際にはどのオートメーション型がカプセル化されているかを示す2バイト整数(vt)を持つ16バイト構造体で、後者の8バイトは値型を格納するために使用できます最大8バイトのポインタ、または別のタイプへの32ビットポインタ。 VBは、内部関数とすべての必要なメモリ割り当てと割り当て解除を使用して、VB型とVariant間のすべての必要な変換を行います。バリアントには、オブジェクトへのポインタをVariantにコピーし、オブジェクトのAddRef()メソッドを呼び出すことによって、COMオブジェクトへの参照を含めることができます。

+0

これは、この件に関して優れたprecis、マークです。 – BobRodes

+0

私が見ることのできる唯一の有益なエラボレーションは、遅延バインディングをサポートしているオブジェクトとサポートしていないオブジェクトを区別する厄介な世界に入りたくないため、VBがデュアルインタフェースを公開するCOMオブジェクトを直接サポートしていることだけです。一方、これは厳密な制限ではありません.iUnknown型の変数を持つSendMessageおよびEM_GETOLEINTERFACEを使用することにより、排他的に初期バインドされたCOMクラスへのインターフェイスを取得することが可能です。 – BobRodes

5

私は別の問題にこれを打破してみましょう:

まず、VB6はVB.Netではないと.NET Frameworkを使用していないが、代わりに古いCOMフレームワークを使用しています。 (あなたがすでにこれを知っているかどうかは分かりません)。

は第二に、どのようなあなたのリンクを指していることは本当にVB6に組み込みクラスです。はい、それは「オブジェクト」と呼ばれます。彼らの卑劣な用語。

第3に、おそらく最も重要なのは、VB6ではすべてがオブジェクトではなく、オブジェクトはデータ型のデフォルトカテゴリまたは支配的カテゴリでさえありません。つまり、.Netのバリュー型のようなものですが、全体的にはそれほど多くありません(ほとんどの場合、実行時の型コンテナはなく、メモリ内のアドレスだけです)。

ほとんどのデータ項目はオブジェクトではないため、クラスを持たないため、継承を持たないため、他のものから派生したものではないため、「型階層」を持たないため、彼らの型階層の「最上位」に何かがありました(しかし、クラス/オブジェクトであったものはすべてこれを持っていました)。したがって、他のデータ型に使用できるベース/ルートデータ型がなく、あらゆる種類のパラメータ渡しなどの状況で問題になっていました。

バリアントは、この問題に対処するために、以前のバージョンのVBでは(VBのオブジェクトより前に)実装された、この問題に対する先の解決策の一種でした。バリアントは、の別の項目をすべてデータ型でラップする単なる動的記述子です。あなたがそれを使用するとき、それはあなたがそれが含んでいるものを直接使用しているように(一般的に)動作しますが、からまで現在行くことになります。

バリアント自体は、そのコンテンツのデータ型が何であるかを追跡し、バリアントにアクセスするVBコードが異なる/適切に動作するようにします(プリミティブな多態性)。

これはそのクルージングのように聞こえて、オーバーヘッドが多かったのですが、それはそうでした。しかし、その時点では、「あらゆるデータ型」を扱う必要があるときに、これは最高の解決策でした。

+0

VB6はCOMベースの言語であり、.NETフレームワークに基づいていません。私の質問は、具体的には異形についてです。 – w0051977

+1

私はそこに着いています... :) – RBarryYoung