更新履歴:No.1
更新時間: 2001-11-01 20:09
更新者: Musicwind®
更新メモ: 最初の草案が完成しました。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
まとめ:
この記事では、Dll 内のクラス (特定の抽象クラスに基づく多くのサブクラス) をエクスポートする方法について説明します。この技術はポリモーフィズムの考え方を利用しており、プラグインと同様の効果を得ることができます。
対象読者:
ポリモーフィズムの概念を理解する。メタクラスの概念を理解する。
技術的な難易度:
6/10 。
DLL からクラスをエクスポートするには、最初に bpl パッケージを使用することを考えなければなりません。この方法の欠点の 1 つは、ユーザーがパッケージにどのクラスが含まれているかを知る必要があることです。つまり、クラスの名前を知っている必要があります。これは、ユーザーが最下層を定義する状況を想像してみてください。抽象クラス、そして多くのアプリケーション クラス (具体的なクラス) class) の場合、ユーザーは、特定のクラスを知らなくてもこれらのクラスを使用できることを望んでいます。これを言うのは少し不思議に思えますが、実際の状況は実際に当てはまります。抽象を定義するときに予測できないためです。クラス 将来的には具体的にどのくらいのクラスが存在するのでしょうか? それでは、そのような需要を実現するにはどのようなテクノロジーが必要になるのでしょうか?
実際、それを実装する技術的な難しさはそれほど難しくありません。著者はここで、新しいアイデアを引き寄せる方法として、自分の実際の経験をすべての人に捧げ、他のより良い方法を期待しています。
以下では、まずこの方法に関連するいくつかの基本的な知識を紹介し、次に例を使用して具体的な実装を説明します。
1. 基本的な考え方
メタクラス(メタクラス)はクラス参照型(クラス参照型)とも呼ばれ、クラスの型とみなすことができ、この型で宣言された変数の値がクラスを表します。例えば:
タイプ
TClass = TObject のクラス;
これはメタクラス型を宣言します。次に、次のような変数宣言を行うことができます。
ヴァール
Aクラス: Tクラス;
次に、次のように使用できます。
Aクラス := TObject;
または:
Aクラス := Tボタン;
または:
Aクラス := TForm;
等
TClass は TObject 型のメタクラスであり、TButton、TForm などはすべて TObject から派生するため、TButton や TForm などの値は AClass に受け入れられます。
そこで、ポリモーフィズムの考え方を利用して、クラス変数 AClass を柔軟に使用することができます。これは、以下の特定の実装のための基礎知識でもあります。
2. 具体的な実装
最初のステップは、抽象クラスを作成することです。
このような単純な宣言を使用します。抽象クラスは抽象メソッドを提供するだけですが、問題の説明には影響しません。
TMyBaseForm = クラス(TForm)
保護されています
関数 GetTitle: 仮想;
終わり;
MyBaseFormClass = TMyBaseForm のクラス;
私たちが議論したいのは技術的な実現可能性であるため、このような抽象クラスがどれほど多くの実用的なメソッドとインターフェイスを提供するかについては議論しません。このインターフェースを定義する際の作成者の本来の意図は、変化するタイトルを任意の数取得することであり、GetTitle の特定の戻り値はサブクラスによって実装する必要があると仮定します。さらに、作者は、サブクラスのコードを Dll で実装し、メイン プログラムから分離できることを望んでいます。この方法はプラグインの風味があり、Plug&Play の一部の機能も実現できる可能性があります。なかなかうまくいきませんか?魅力的?それで、次に何をすべきでしょうか?
まず、メイン プログラムと Dll プログラムには、上で宣言したユニットが含まれている必要があります。次に、メイン プログラムは、Dll とクラスを動的にロードするドライバーの実装を担当し、Dll はサブクラスを実装します。
まず Dll について話しましょう。Dll は何をすべきでしょうか?
2 番目のステップは、 Dll内のサブクラスをエクスポートすることです。
次の 2 つのエクスポート関数を設計しました。
1.関数 GetClassCount: 整数;
この DLL にはいくつかのサブクラスがあることを呼び出し元に伝えます。
2. function GetClassTypeByIndex(const iIndex: integer;
var クラスタイプ: MyBaseFormClass): WordBool;
インデックスによって特定のサブクラスを取得します。ここでの ClassType のタイプは MyBaseFormClass であることに注意してください。これは、その値が TMyBaseForm から継承された明確なクラスであることを示しています。
以下に、それらの考えられる実装の 1 つを示します。
関数 GetClassCount: 整数;
始める
result := 3; //この DLL で 3 つのクラスがエクスポートされることを示します
終わり;
function GetClassTypeByIndex(const iIndex: integer;
var ClassType: MyBaseFormClass): WordBool;
始める
結果 := True;
ケース iIndex の
0: クラスタイプ := TFrmTest1;
1: クラスタイプ := TFrmTest2;
2: クラスタイプ := TFrmTest3;
それ以外
結果 := False;
終わり;
終わり;
もちろん、TFrmTest1、TFrmTest2、および TFrmTest3 が配置されているユニットは、ユニットの使用リストに含まれている必要があります。 TFrmTest1 の実装は次のようになります。
TFrmTest1 = クラス(TMyBaseForm)
保護された
関数 GetTitle: PChar をオーバーライドします。
終わり;
関数 TFrmTest1.GetTitle: Pchar;
始める
結果 := 'TFrmTest1 からこんにちは';
終わり;
最後に、GetClassCount と GetClassByIndex をエクスポート リストに追加することを忘れないでください。次に、Dll プロジェクトをビルドするときに、プロジェクト オプション パッケージの「ランタイム パッケージを使用する」にチェックを入れてください。具体的な理由については後述します。
この時点で、Dll に関する作業は終了しました。
3 番目のステップは、メイン プログラム ドライバー エンジンの実装です。
この手順は比較的簡単です。Dll を動的にロードして、GetClassCount 関数を呼び出し、次に GetClassByIndex を呼び出すだけです。キーコード:
変数 AClass: TMyBaseClass;
Aフォーム: TMyBaseForm;
I、iCount: 整数;
blResult: ブール値;
始める
// FPGetClassProc が GetClassCount 関数を指し、FPGetClassByIndexProc が GetClassByIndex を指すと仮定して、ダイナミック ライブラリのロードに関する部分を省略します。その後、次のようになります。
iCount := FPGetClassProc;
for I := 0 to iCount ?C 1 do
始める
AClass := FPGetClassByIndex(I, blResult);
blResult の場合、その後
始める
AForm := AClass.Create(アプリケーション);
AForm.Caption := AForm.GetTitle;
AForm.Show;
終わり;
終わり;
//…
終わり;
Dll と同様に、出力ファイルを作成するときにランタイム パッケージの使用を選択する必要があることに注意してください。これは、ランタイム パッケージを使用しないと同じクラスのコピーがメモリ内に複数存在することになり、それらに対して Is 演算子を使用すると False の結果が返されるためです。
Musicwind®@杭州、浙江省、中国
2001-11-01
その他の記事
[記事の終わり]