我目前正在研究一些插件概念,并且在我使用dll或BPls的研究过程中遇到过,我现在决定使用bpls。
我想知道何时必须使用UnloadPackage(包模块);最好的观点,因为加载后立即给我什么都没有,因为形状然后立即消失
当前的计划结构
Hostapplication(PackageLoader.exe)
|_Plugin.bpl
|_TPluginForm
PackageLoader.exe
var
PackageModule : hModule;
createProc: Procedure;
begin
// Package laden
try
PackageModule := LoadPackage('plugin.bpl');
If PackageModule <> 0 then
begin
@createProc := GetProcAddress( PackageModule, 'CreatePluginForm' ); // Funktion aus den Exports aufrufen
if Assigned(CreateProc) then
CreateProc
else
ShowMessage('GetProcAddress failed');
end;
finally
//UnloadPackage(PackageModule);
end;
end;
plugin.bpl - uPlugin.pas
unit uPlugin;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TPluginForm = class(TForm)
Memo1: TMemo;
Panel1: TPanel;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
PluginForm: TPluginForm;
Status: Boolean;
implementation
uses
uRandomString;
{$R *.dfm}
procedure TPluginForm.Button1Click(Sender: TObject);
var
User, pwd, mail: String;
ul, pl, ml: Integer;
begin
Status := True;
ul := StrToInt(Edit1.Text);
pl := StrToInt(Edit2.Text);
// ml := StrToInt(Edit3.Text);
while Status do
begin
Application.ProcessMessages;
User := RandomString(ul);
pwd := RandomString(pl);
//mail := RandomString(ml) + '@' + RandomString(5)+'.de';
Memo1.Lines.Add(User+':'+pwd); //+':'+mail);
end;
end;
procedure TPluginForm.Button2Click(Sender: TObject);
begin
Status := False;
end;
function CreatePluginForm(ApplicationHandle, ParentHandle: THandle): boolean;
begin
Result := False;
PluginForm := TPluginForm.Create(nil);
try
PluginForm.Show;
//PluginForm.ShowModal;
finally
end;
end;
exports
CreatePluginForm;
initialization
RegisterClass(TPluginForm);
finalization
UnRegisterClass(TPluginForm);
end.
答案 0 :(得分:2)
何时卸载软件包取决于应用程序的设计。鉴于我们对此并不了解,很难给出具体的建议。一种选择是您不要卸载包裹。为什么你觉得你需要这样做?如果需要卸载,则必须确保程序包中的代码仍未运行。您显示包中的表单。当您卸载包装时,该表格必须已被销毁。
我能看到的一个大问题是导入该功能的方式。它在包中声明如下:
function CreatePluginForm(ApplicationHandle, ParentHandle: THandle): Boolean;
begin
....
end;
exports
CreatePluginForm;
然后你像这样导入它:
var
createProc: Procedure;
....
@createProc := GetProcAddress(PackageModule, 'CreatePluginForm');
if Assigned(CreateProc) then
CreateProc
您需要使用匹配的签名声明createProc
:
var
createProc: function(ApplicationHandle, ParentHandle: THandle): Boolean;
然后当你调用它时,你需要传递两个句柄,并使用返回值做一些事情。
您的代码也泄漏PluginForm
。
最后,THandle
似乎是错误的类型。我认为你打算使用HWND
。虽然我不明白为什么你不能通过VCL对象。毕竟,您选择使用包,这意味着您可以直接传递父控件。而且您当然不需要传递与应用程序相关的任何内容,因为该插件已经可以看到该应用程序。