ホームページ 类库下载 その他の図書館 Delphi で動的パッケージを使用する理由

Delphi で動的パッケージを使用する理由

Nov 21, 2016 am 11:34 AM
delphi

なぜバッグを使うのですか?

答えは簡単です。パッケージの強力な機能のためです。設計時パッケージはカスタム コンポーネントのリリースとインストールを簡素化し、実行時パッケージは従来のプログラミングに新たな力を注入します。再利用可能なコードをランタイム ライブラリにコンパイルすると、それを複数のアプリケーション間で共有できます。すべてのアプリケーションは、パッケージを通じて標準コンポーネントにアクセスできます。これは、Delphi 自体が行う方法です。アプリケーションは実行可能ファイル内の別のコンポーネント ライブラリをコピーする必要がないため、システム リソースとディスク領域が大幅に節約されます。さらに、パッケージを使用すると、アプリケーション固有のコードのみをコンパイルするだけで済むため、コンパイルにかかる時間が短縮されます。

パッケージを動的に使用できれば、より多くのメリットを得ることができます。パッケージは、アプリケーション開発に対する新しいモジュール式アプローチを提供します。場合によっては、オプションの HR モジュールが付属する会計システムなど、特定のモジュールをアプリケーションのオプション コンポーネントにしたい場合があります。基本アプリケーションのみをインストールする必要がある場合もあれば、追加の HR モジュールをインストールする必要がある場合もあります。このモジュール式のアプローチは、パッケージ技術を通じて簡単に実装できます。これまでは、DLL を動的にロードすることによってのみこれを実現できましたが、Delphi のパッケージング テクノロジを使用すると、アプリケーションの各モジュール タイプをバンドルに「パッケージ化」することができます。特に、パッケージから作成されたクラス オブジェクトはアプリケーションによって所有されるため、アプリケーション内のオブジェクトと対話できます。

ランタイム パッケージとアプリケーション

多くの開発者は、Delphi パッケージをコンポーネントを配置する場所としてのみ考えています。実際、パッケージはモジュール型アプリケーション設計で使用できます (またそうすべきです)。

パッケージを使用してアプリケーションをモジュール化する方法を示すために、次の例を作成します。

1. Form1 と Form2 の新しい Delphi プログラムを作成します。

2. Form2 からフォームを自動的に作成します。プロジェクト | オプション | フォーム);

3. ボタンの OnClick イベント ハンドラーに次のコードを入力します。

4. Unit2 を Unit1 の子に追加します。 5. プロジェクトを保存して実行します。

ボタン付きのフォームを表示するシンプルなアプリケーションを作成しました。このボタンをクリックすると、別のフォームが作成されて表示されます。

しかし、上記の例の Form2 を再利用可能なモジュールに組み込み、引き続き正常に動作するようにしたい場合は、どうすればよいでしょうか?

答えは「バオ」です!

Form2 のパッケージを作成するには、次の作業が必要です:

1. プロジェクト マネージャーを開きます ([表示]、[プロジェクト マネージャー])

2. プロジェクト グループを右クリックし、[新しいプロジェクトの追加...] を選択します。

3. [新しい] プロジェクト リストで、[パッケージ] を選択します。

5. [含む] プロジェクトを選択し、[追加] ボタンをクリックします。 ;

6. [参照] ボタンをクリックして、[Unit2.pas] を選択します

8. 最後に、パッケージを保存してコンパイルします。

これでパッケージが完成しました。 ProjectBPL ディレクトリに「package1.bpl」という名前のファイルがあるはずです。 (BPLはBorland Package Libraryの略、DCPはDelphi CompiledPackageの略です。)

このパッケージは完成しました。次に、パッケージ オプション

をオンにして、元のアプリケーションを再コンパイルする必要があります。

1. プロジェクトマネージャーで「Project1.exe」をダブルクリックしてプロジェクトを選択します。

2. 右クリックして「オプション...」を選択します (メニューから「プロジェクト」→「オプション...」を選択することもできます)。 );

3. [パッケージ] オプション ページを選択します。

4. [ランタイム パッケージを使用してビルド] チェック ボックスを選択し、[Vcl50;Package1] をクリックします。 「OK」ボタン

6. 注: Unit2 をアプリケーションから削除しないでください。

7.

アプリケーションは以前と同じように実行されますが、違いはファイルサイズに見られます。

Project1.exe のサイズは、以前は 293K でしたが、現在はわずか 14K です。リソース ブラウザを使用して EXE ファイルと BPL ファイルの内容を表示すると、Form2 DFM とコードがパッケージに保存されていることがわかります。

Delphi はコンパイル中にパッケージの静的リンクを完了します。 (これが、EXE プロジェクトから Unit2 を削除できない理由です。)

これから何が得られるかを考えてください: パッケージ内にデータ アクセス モジュールを作成でき、データ アクセス ルールを変更するとき (たとえば、からの切り替えなど) ADO 接続用の BDE 接続)を少し変更して、このパッケージを再公開します。あるいは、「このオプションは現在のバージョンでは使用できません」というメッセージを表示するフォームを 1 つのパッケージ内に作成し、完全に機能するフォームを同じ名前の別のパッケージ内に作成することもできます。今では、手間をかけずに製品を「プロ」バージョンと「エンタープライズ」バージョンで利用できるようになりました。

パッケージの動的なロードとアンロード

在大多数情况下,静态连接的DLL或BPL已经可以满足要求了。但是如果我们不想发布BPL呢? “在指定目录中找不到动态链接库Package1.bpl”,这是在应用程序终止前,我们所能得到 的唯一消息。或者,在模块化应用程序程序中,我们是否可以使用任意数量的插件?

我们需要在运行期动态连接到BPL。

对于DLL 来说,有一个简单的方法,就是使用LoadLibrary函数:

function LoadLibrary(lpLibFileName: Pchar): HMODULE;stdcall;

装载了DLL之后,我们可以使用GetProcAddress函数来调用DLL的导出函 数和方法:

function GetProcAddress(hModule: HMODULE; lpProcName:LPCSTR): FARPROC; stdcall;

最后,我们使用FreeLibrary卸载DLL:

function FreeLibrary(hLibModule: HMODULE): BOOL;stdcall;

下面这个例子中我们动态装载Microsoft的HtmlHelp库:

function TForm1.ApplicationEvents1Help(Command: Word; Data: Integer; var CallHelp: Boolean):Boolean;
type
TFNHtmlHelpA = function(hwndCaller: HWND; pszFile: PansiChar; uCommand: UINT;dwData: Dword): HWND; stdcall;
var
HelpModule: Hmodule;
HtmlHelp: TFNHtmlHelpA;
begin
Result := False;
HelpModule := LoadLibrary('HHCTRL.OCX');
if HelpModule <> 0 then
begin
@HtmlHelp := GetProcAddress(HelpModule, &#39;HtmlHelpA&#39;);
if @HtmlHelp <> nil then
Result := HtmlHelp(Application.Handle,Pchar(Application.HelpFile), Command,Data) <> 0;
FreeLibrary(HelpModule);
end;
CallHelp := False;
end;
ログイン後にコピー

动态装载BPL

我们可以用同样简单的方法来对付BPL,或者应该说基本上同 样简单。

我们可以使用LoadPackage函数动态装载包:

function LoadPackage(const Name: string): HMODULE;

然后使用GetClass 函数创建一个TPersistentClass类型对象:

function GetClass(const AclassName: string):TPersistentClass;

完成所有操作后,使用UnLoadPackage(Module:HModule);

让我们对原来的代码作一些小小的改动:

1、 在工程管理器中选中“Project1.exe”;

2、 右击之并选择“Options...”;

3、 选中“Packages”选项页;

4 、 从“Runtime packages”编辑框中移除“Package1”,并点击OK按钮;

5、 在Delphi的工具栏中,点击“Remove file from project”按钮;

6、 选择“Unit2 | Form2”,并点击OK;

7、 现在在“Unit1.pas”的源代码中,从uses子句中移除Unit2;

8、 进入Button1 的OnClick时间代码中;

9、 添加两个HModule和TPersistentClass类型的变量:

var

PackageModule: HModule;

AClass: TPersistentClass;

10、使用LoadPackage 函数装载Pacakge1包:

PackageModule := LoadPackage('Package1.bpl');

11、检查PackageModule是否为0;

12、使用GetClass函数创建一个持久类型:

AClass := GetClass('TForm2');

13、如果这个持久类型不为nil,我们就可以向从前

一样创建并使用该类型的对象了:

with TComponentClass(AClass).Create(Application) as TcustomForm do
begin
ShowModal;
Free;
end;
ログイン後にコピー

14、最后,使用UnloadPackage 过程卸载包:

UnloadPackage(PackageModule);

15、保存工程。

下面是OnClick事件处理器的完整清单:

procedure TForm1.Button1Click(Sender: Tobject);
var
PackageModule: HModule;
AClass: TPersistentClass;
begin
PackageModule := LoadPackage(&#39;Package1.bpl&#39;);
if PackageModule <> 0 then
begin
AClass := GetClass(&#39;TForm2&#39;);
if AClass <> nil then
with TComponentClass(AClass).Create(Application) as TcustomForm do
begin
ShowModal;
Free;
end;
UnloadPackage(PackageModule);
end;
end;
ログイン後にコピー

不幸的是,并不是这样就万事大吉了。

问题在于,GetClass函数只能搜索到已经注册的类型。 通常在窗体中引用的窗体类和组件类会在窗体装载时自动注册。但是在我们的例子中,窗体无法提前装载。那么我们在哪里注册类型呢?答案是,在包中。包中的每 个单元都会在包装载的时候初始化,并在包卸载时清理。

现在回到我们的例子中:

1、 在工程管理器双击“Package1.bpl”;

2、 点击“Contains”部分“Unit2”旁的+号;

3、 双击“Unit2.pas”激活单元源代码编辑器;

4、 在文件的最后加入initialization部分;

5、 使用RegisterClass过程注册窗体的类型:

RegisterClass(TForm2);

6、 添加一个finalization部分;

7、 使用UnRegisterClass过程反注册窗体的类 型:

UnRegisterClass(TForm2);

8、 最后,保存并编译包。

现在我们可以安全的运行“Project1”,它还会像从前 一样工作,但是现在你可以随心所欲的装载包了。

尾声

记住,无论你是静态还是动态的使用包,都要打开Project | Options | Packages | Build with runtime packages 选项。

在你卸载一个包之前,记得销毁所有该包中的类对象,并反注册所有已注册的类。下面的过程可能会对你有所帮助:

procedure DoUnloadPackage(Module: HModule);
var
i: Integer;
M: TMemoryBasicInformation;
begin
for i := Application.ComponentCount - 1 downto 0 do
begin
VirtualQuery(GetClass(Application.Components[i].ClassName), M, Sizeof(M));
if (Module = 0) or (HMODULE(M.AllocationBase) = Module) then
Application.Components[i].Free;
end;
UnregisterModuleClasses(Module);
UnloadPackage(Module);
end;
ログイン後にコピー

在装载包之前,应用程序需要知道所有已注册类的名字。改善这一情况的方法是建立一个注册机制,以便告诉应用程序所有 由包注册的类的名字。

实例

多重包:包不支持循环引用。也就是说,一个单元不能引用一个已经引用了该单元的单元(嘿嘿)。这使得调用窗体中的某 些值难以由被调用的方法设置。

解决这个问题的方法是,创建一些额外的包,这些包同时由调用对象和包中的对象引用。设想一下我们如何使Application成为所有窗体的拥有者?变量Application创 建于Forms.pas 中,并包含在VCL50.bpl包 中。你大概注意到了你的应用程序既要将VCL50.pas编译进来,也同时你的包也需要(require) VCL50。

3 番目の例では、顧客情報と顧客の注文をオンデマンドで (動的に) 表示するアプリケーションを設計します。

では、どこから始めればよいでしょうか?すべてのデータベース アプリケーション

プログラムと同様に、接続する必要があります。 TDataBase 接続を含むメイン データ モジュールを作成します。次に、このデータ モジュールをパッケージ (cst_main) にカプセル化します。

今度はアプリケーションで顧客フォームを作成し、DataModuleMain を参照します (VCL50 と cst_main を静的にリンクします)。

次に、顧客注文フォームを含む新しいパッケージ (cst_ordr) を作成し、cst_main を要求します。これで、アプリケーションに cst_ordr を動的にロードできるようになりました。メイン データ モジュールはダイナミック パッケージがロードされる前にすでに存在しているため、cst_ordr はアプリケーションのメイン データ モジュール インスタンスを直接使用できます。

上の写真は、このアプリケーションの機能図です:

交換可能パック: パッケージのもう 1 つの応用例は、交換可能パッケージを作成することです。この機能の実装には、パッケージの動的読み込み機能は必要ありません。プログラムの期間限定の試用版をリリースしたいとします。これを実現するにはどうすればよいでしょうか。

まず、「スプラッシュ」フォーム (通常は「トライアル」という単語が含まれた画像) を作成し、アプリケーションの起動プロセス中に表示します。次に、アプリケーションに関する情報を提供する「About」フォームを作成します。最後に、ソフトウェアが古いかどうかをテストする関数を作成します。これら 2 つの形式とこの機能をパッケージにカプセル化し、ソフトウェアの試用版とともにリリースします。

ソフトウェアの有料版では、前の 2 つのフォームと同じクラス名を持つ「スプラッシュ」フォームと「About」フォームも作成し、テスト関数 (何も実行しません) を作成し、それらを同じ名前のパッケージ。

何、何?これは便利ですか?さて、ソフトウェアの試用版を一般公開できます。顧客がアプリを購入した場合は、試用版以外のパッケージを送信するだけで済みます。これにより、インストールと登録パッケージのアップグレードが 1 回だけ必要となるため、ソフトウェア リリース プロセスが大幅に簡素化されます。

パッケージは、Delphi および C++ Builder 開発コミュニティにモジュラー設計への新たな扉を開きます。パッケージを使用すると、ウィンドウ ハンドルを渡す必要がなく、コールバック関数や他の DLL テクノロジも必要ありません。これにより、モジュール型プログラミングの開発サイクルも短縮されます。私たちがしなければならないのは、Delphi のパッケージを機能させることだけです。


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)