BPL 文件需要运行时包!

发布于 2024-10-02 23:14:18 字数 340 浏览 7 评论 0原文

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

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

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

alt text

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

我正在使用 Delphi 2010

非常感谢...

I have created a Package and i want to use the BPL File of my Package ...

My Package have VCL.dcp and RTL.dcp as Required libraries , i load this Package in my application without any errors but when i want to unload it , an Access Violation shown !

If i Build my Application with Run-Time Packages ( "vcl" and "rtl" ) , Access Violation not shown !

alt text

What is this mean ?! My Application need VCL and RTL Libraries to Load BPLs ?! I want to Load my Package like a DLL File , is there any solution ?

I`m using Delphi 2010

thanks a lot ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

千年*琉璃梦 2024-10-09 23:14:18

您的 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 中找到的参数类型的函数,例如整数、字符指针和记录指针,而不是字符串或对象。

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

Your BPL requires the RTL and VCL packages. If your Application doesn't require them, then that means the RTL and VCL units are compiled into your EXE file. When your EXE loads your BPL, you now have two copies of the RTL and VCL units — one set of copies comes from within the EXE, and the second copies come from the RTL and VCL packages that your package implicitly causes to be loaded.

Delphi isn't intended to accommodate that situation. It's possible that you have memory that was allocated by one RTL and attempted to get freed by the other RTL. Or there might be function pointers in the EXE that refer to functions that were in the VCL package.

I see three options for you:

  1. Compile your EXE to use packages. Specifically, it should require the same RTL and VCL packages that your BPL requires.

  2. Make your BPL not require any other packages. If it doesn't require RTL and VCL, then any RTL and VCL units that your package uses will get compiled into your BPL. You'll end up with two separate copies again, but it should work better since neither copy will think it's supposed to be shared.

  3. Load your package like a real DLL instead of like a package. You said you wanted to use it like a DLL, so do that. Use LoadLibrary, and then use GetProcAddress to get whatever functions you want to call. If you go this route, it's probably better to not make your code be a package at all. Make it a DLL, and export functions that only use parameter types that you'd expect to find in other DLLs, like integers, character pointers, and record pointers, not strings or objects.

It should be clear that the first option is the easiest. The second could probably work, and it sounds like that's the way you'd prefer, but I expect it will generate more headaches before it finally works. The third option is best if you'll ever have to use other development environments during the lifetime of this project.

°如果伤别离去 2024-10-09 23:14:18

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

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

添加:我认为当您尝试 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.

包被加载并且表单可视化没有问题,与Close和Unload操作相同。该项目是使用“使用 rutime 包构建”未选中进行编译的。

您可以发布任何代码吗?

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

[2644] 正在加载包
[2644] 开始_P 创建表单
[2644] 准备卸载包裹
[2644服]第2644服[双线] 新服
[2644] 已卸载

问候。

What have your package inside?
What work do you do with it?
How do you charge and discharge? What's in it?

What do you do with the package before unload it?
When you Unload it, all the objects/forms/components/... that yo've used is released?

ADDED: I Think that you are using anything of the package when you try to Onload. This is the reason of AV.

In an EXE compiled without runtime package, I load the package:

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

I Unload the package with this code:

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

The package has a unit with a form (form1) and a unit Init.pas, for initialization like this:

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.

The package is loaded and the form visualized without problems, and the same with the operation of Close and Unload. The project is compiled with "Build with rutime packages" unchecked.

Can you post any code.

The result of OutputDebugString is this (no AV error):

[2644] Loading the package
[2644] Start_P Creating form
[2644] Ready to Unload Package
[2644] Finish_P form free
[2644] Unloaded

Regards.

↘人皮目录ツ 2024-10-09 23:14:18

感谢您的帮助...

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

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

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

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节目就出来了!

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

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

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

非常感谢...

Thanks for your helps ...

I put an example of my package and my Application here to Find what is the problem !

We have a package without requiring to Run-Time Packages like VCL and RTL , in other words i removed all libraries from the Requires section in my package :
alt text

my package contains a form with code below :

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.

I Load this Package and Call ShowForm Function and then Unload package :

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;

After the Procedure above done , the AV Shows !

@Neftalí : If I just do loading and unloading the Package , no AV Shows , but i think that is because i don`t call some routines or objects or ... that they need VCL or RTL Libraries , if i use objects and functions and ... of this package , after using them i will get an AV ...
is it true ?!

If I Build my application with Run-Time package ( VCL and RTL ) no AV will shown !

I`m confusing !! , I want to use an BPL package without any Run-Time package needed ...

thanks a lot ...

污味仙女 2024-10-09 23:14:18

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

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

Yes, if you want to use runtime packages in your application you have to build it with runtime packages, and then it requires them (links statically with them).

The solution to your problem depends on what the problem actually is (which is unclear at the moment).

笑忘罢 2024-10-09 23:14:18

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

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

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

当您定义函数的 sataxis 时也是如此:

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

测试它并说出结果。

问候。

Ohhhhh, great oversight/neglect (mine).
With the code that you have posted, made a simple change a test it (use PChar).

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

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

The same when you define the sitaxis of the function:

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

Test it and say the result.

Regards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文