1

我创建了一个包,我想使用我的包的 BPL 文件...

我的包有 VCL.dcp 和 RTL.dcp 作为必需的库,我在我的应用程序中加载这个包没有任何错误,但是当我想卸载它时,显示访问冲突!

如果我使用运行时包(“vcl”和“rtl”)构建我的应用程序,则不会显示访问冲突!

替代文字

这是什么意思 ?!我的应用程序需要 VCL 和 RTL 库来加载 BPL?!我想像 DLL 文件一样加载我的包,有什么解决方案吗?

我正在使用德尔福 2010

多谢 ...

4

5 回答 5

8

您的 BPL 需要 RTL 和 VCL 包。如果您的应用程序不需要它们,那么这意味着 RTL 和 VCL 单元被编译到您的 EXE 文件中。当您的 EXE 加载 BPL 时,您现在拥有RTL 和 VCL 单元的两个副本— 一组副本来自 EXE 内部,第二个副本来自您的包隐式导致加载的 RTL 和 VCL 包。

Delphi 并不打算适应这种情况。您的内存可能由一个 RTL 分配并试图由另一个 RTL 释放。或者,EXE 中可能存在引用 VCL 包中的函数的函数指针。

我为您看到了三个选项:

  1. 编译您的 EXE 以使用包。具体来说,它应该需要您的 BPL 所需的相同 RTL 和 VCL 包。

  2. 使您的 BPL不需要任何其他包。如果它不需要 RTL 和 VCL,那么您的包使用的任何 RTL 和 VCL 单元都将被编译到您的 BPL 中。您最终将再次获得两个单独的副本,但它应该会更好地工作,因为两个副本都不会认为它应该被共享。

  3. 像一个真正的 DLL 而不是像一个包一样加载你的包。你说你想像 DLL 一样使用它,那么就这样做吧。使用LoadLibrary, 然后使用GetProcAddress来获取您想要调用的任何函数。如果你走这条路,最好不要让你的代码成为一个包。将其设为 DLL,并导出仅使用您希望在其他 DLL 中找到的参数类型的函数,例如整数、字符指针和记录指针,而不是字符串或对象。

应该清楚,第一个选项是最简单的。第二个可能会起作用,听起来这是您更喜欢的方式,但我预计它会在最终起作用之前产生更多的头痛。如果您在该项目的生命周期内必须使用其他开发环境,则第三种选择是最好的。

于 2010-11-17T15:52:18.170 回答
1

你的包裹里面有什么?
你用它做什么工作?
你如何充电和放电?这里面是什么?

在卸载之前你会如何处理包裹?
当您卸载它时,您使用的所有对象/表单/组件/...都被释放?

添加:我认为您在尝试 Onload 时正在使用该软件包的任何内容。这就是AV的原因。

在没有运行时包编译的 EXE 中,我加载包:

  OutputDebugString(PChar('Loading the package'));
  hand := LoadPackage('r:\rrrrrrr\Package1.bpl');

我使用以下代码卸载包:

  OutputDebugString(PChar('Ready to Unload Package'));
  UnloadPackage(hand);
  OutputDebugString(PChar('Unloaded'));

该包有一个带有表单(form1)的单元和一个单元Init.pas,用于像这样的初始化:

unit Init;

interface

// prototipos
procedure Start_P;
procedure Finish_P;

implementation

uses
  Unit1, Windows;

procedure Finish_P();
begin
  OutputDebugString(PChar('Finish_P   form free'));
  Form1.Free;
end;


procedure Start_P();
begin
  OutputDebugString(PChar('Start_P   Creating form'));
  Form1 := TForm1.Create(nil);
  Form1.Show;
end;

Initialization;
  Start_P();

Finalization;
  Finish_P();

end.

包被加载,表格可视化没有问题,关闭和卸载的操作也是如此。该项目是在未选中“使用 rutime 包构建”的情况下编译的。

你可以发布任何代码。

OutputDebugString 的结果是这样的(没有 AV 错误):

[2644] 加载包
[2644] Start_P 创建表单
[2644] 准备卸载包
[2644] Finish_P 表单免费
[2644] 已卸载

问候。

于 2010-11-17T15:59:20.383 回答
1

感谢您的帮助...

我在这里放了一个我的包和我的应用程序的例子来查找问题所在!

我们有一个包,不需要像 VCL 和 RTL 这样的运行时包,换句话说,我从包的 Requires 部分中删除了所有库: 替代文字

我的包裹包含一个带有以下代码的表格:

unit MyUnit;

interface

uses
  Windows, Forms, StdCtrls, Buttons, Controls, Classes, Dialogs;

type
  TMyForm = class(TForm)
    MyLabel: TLabel;
    MyEdit: TEdit;
    PostBtn: TBitBtn;
    procedure PostBtnClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MyForm: TMyForm;

implementation

{$R *.dfm}

function ShowForm(FCaption, LCaption : String) : String;
var
 F : TMyForm;
begin
 F := TMyForm.Create(nil);
 try
  F.Caption := FCaption;
  F.MyLabel.Caption := LCaption;
  F.ShowModal;
 finally
  Result := F.MyEdit.Text;
  F.Free;
 end;
end;

procedure TMyForm.PostBtnClick(Sender: TObject);
begin
 if MyEdit.Text <> '' then
  Close
 else
  ShowMessage('Please Enter Value !');
end;

exports
 ShowForm;

end.

我加载这个包并调用 ShowForm 函数,然后卸载包:

var
 ShowF : function(FCaption, LCaption : String) :  String;
 MyPkg : HMODULE;
 FC, LC : String;
begin
 MyPkg := LoadPackage(ExtractFilePath(Application.ExeName)+'MyPackage.bpl');
 FC := 'Enter Value ... ';
 LC := 'Value : ';
 if MyPkg <> 0 then
  begin
   try
    @ShowF := GetProcAddress(MyPkg, 'ShowForm');
    if Assigned(ShowF) then
     Edit1.Text := ShowF(FC, LC)
    else
     ShowMessage('Function not found !');
   finally
    UnloadPackage(MyPkg);
   end;
  end;
end;

完成以上步骤后,AV Shows!

@Neftalí:如果我只是加载和卸载包,没有 AV 节目,但我认为这是因为我不调用某些例程或对象,或者......如果我使用对象和函数,它们需要 VCL 或 RTL 库还有……这个包,用完后我会得到一个AV……是真的吗?!

如果我使用运行时包(VCL 和 RTL)构建我的应用程序,则不会显示任何 AV!

我很困惑!,我想使用不需要任何运行时包的 BPL 包...

多谢 ...

于 2010-11-17T17:03:17.033 回答
0

是的,如果你想在你的应用程序中使用运行时包,你必须用运行时包构建它,然后它需要它们(与它们静态链接)。

您的问题的解决方案取决于问题的实际情况(目前尚不清楚)。

于 2010-11-17T15:29:06.360 回答
0

Ohhhhh,很大的疏忽/忽视(我的)。
使用您发布的代码,对其进行简单的更改测试(使用 PChar)。

function ShowForm(FCaption, LCaption : String) : PChar;  
...

    Result := PChar(F.MyEdit.Text);
  ...

定义函数的坐标轴时也是如此:

 ShowF : function(FCaption, LCaption : String):PChar;

测试它并说出结果。

问候。

于 2010-11-18T10:30:11.170 回答