[英]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軟件包中的函數。
我為您提供了三種選擇:
編譯您的EXE以使用軟件包。 具體來說,它應要求使用與BPL相同的RTL和VCL軟件包。
讓你的BPL 不需要任何其他包。 如果不需要RTL和VCL,則軟件包使用的任何RTL和VCL單元都將編譯到BPL中。 您將再次獲得兩個單獨的副本,但是它應該會更好,因為兩個副本都不認為應該共享。
像真實的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.