簡體   English   中英

BPL文件需要運行時軟件包!

[英]BPL File needs Run-Time Packages !

我已經創建了一個軟件包,並且想使用我的軟件包的BPL文件...

我的軟件包具有VCL.dcp和RTL.dcp作為必需的庫,我將此軟件包加載到我的應用程序中沒有任何錯誤,但是當我要卸載它時,顯示訪問沖突!

如果我使用運行時程序包(“ vcl”和“ rtl”)構建應用程序,則不會顯示訪問沖突!

替代文字

這是什么意思 ?! 我的應用程序需要VCL和RTL庫來加載BPL嗎? 我想像DLL文件一樣加載我的包,有什么解決方法嗎?

我正在使用Delphi 2010

非常感謝 ...

您的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中找到的參數類型的函數,例如整數,字符指針和記錄指針,而不是字符串或對象。

應該清楚的是,第一種選擇是最簡單的。 第二個可能會起作用,聽起來這是您喜歡的方式,但是我希望它在最終起作用之前會引起更多的麻煩。 如果您在該項目的整個生命周期中不得不使用其他開發環境,則第三個選項是最好的。

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

在卸載之前,您如何處理包裝?
當您卸載它時,您使用的所有對象/表單/組件/ ...都會被釋放?

添加:我認為您嘗試加載時正在使用任何軟件包。 這就是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]已卸載

問候。

感謝您的幫助...

我在這里放了一個包和我的應用程序示例,以查找問題所在!

我們有一個軟件包,不需要像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會顯示!

@Neftalí:如果我只是加載和卸載軟件包,則不會顯示任何AV節目,但是我認為這是因為我不調用某些例程或對象,或者...如果我使用對象和函數,則它們需要VCL或RTL庫和...的包裝,使用它們后,我會得到一個AV ...是真的嗎?

如果我使用運行時程序包(VCL和RTL)構建應用程序,則不會顯示AV!

我很困惑! ,我想使用不需要任何運行時軟件包的BPL軟件包...

非常感謝 ...

是的,如果要在應用程序中使用運行時程序包,則必須使用運行時程序包構建它,然后需要它們(與它們靜態鏈接)。

解決問題的方法取決於問題的實質(目前尚不清楚)。

呵呵,疏忽大意(我的)。
使用您發布的代碼,對測試進行簡單的更改(使用PChar)。

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

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

定義函數的坐軸時相同:

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

測試並說出結果。

問候。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM