簡體   English   中英

動態加載BPL在LoadLibrary中失敗

[英]Dynamically loading BPL fails in LoadLibrary

我想在Delphi 10 Seattle(更新1)或Delphi 10.1 Berlin項目(企業版)中動態加載BPL模塊。 但是LoadPackage函數失敗並顯示消息(在32位和64位目標平台上):


Project LoadPackageTest.exe引發異常類EPackageError,並顯示消息“無法在此處加載程序包的真實路徑” \\ TestBplPackage.bpl。 指定的模塊無法找到'。


我的開發平台是Windows 10 Pro 64位。

我確定傳遞的文件名正確(包含完整路徑)。 我到目前為止所做的:

  • 如果在同一台Win 10 PC上使用Delphi 2007 Enterprise進行編譯,則相同的項目組可以正常工作(我必須從頭開始重新創建它)

  • 如果我加載標准.DLL-它將正確加載,並且可以在D2007,D10和D10.1中調用函數(適用於D10和D10.1上的32位和64位目標)。

實際上,LoadPackage調用了SafeLoadLibrary,后者調用了LoadLibrary(所有這些過程都在System.SysUtils中。

我編譯了帶有和不帶有運行時軟件包的測試可執行文件,其中包含代碼:

DLL項目(TestDLL.dpr),在所有情況下均有效

library TestDLL;
uses SysUtils, Classes;
{$R *.res}
function GetMyTime: TDateTime; stdcall; 
begin 
  Result:= Now; 
end;
exports GetMyTime;
end.

BPL項目(TestBplPackage.dpr)

package TestBplPackage;
{ standard compiler directives - the project was created with New->Package}
requires
  rtl,
  vcl; 
contains
  TestBPLUnit in 'TestBPLUnit.pas';
end.

unit TestBPLUnit;
interface
function GetMyTime: TDateTime; stdcall;

implementation 
uses  classes, sysutils;  

function GetMyTime: TDateTime;
begin  
  Result:= Now;
end;
exports  GetMyTime;
end.

測試應用程序-LoadPackageTest.dpr

Form1:TForm包含dOpen:TOpenDialog和一個Button1:TButton

type
  TMyDateTimeFunction = function: TDateTime; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
  ext: string;
  h: HModule;
  func: TMyDateTimeFunction;
begin
  if dOpen.Execute then begin
    ext:= ExtractFileExt(dOpen.FileName);
    if SameText(ext, '.bpl') then begin
      h:= LoadPackage(PChar(dOpen.FileName));
      if h > 0 then begin
        func:= GetProcAddress(h, 'GetMyTime');
        if Assigned(func) then
          ShowMessage(FormatDatetime('yyyy-mm-dd hh:nn:ss', func));
        UnloadPackage(h);
      end;
    end else if SameText(ext, '.dll') then begin
      h:= LoadLibrary(PChar(dOpen.FileName));
      if h > 0 then begin
        func:= GetProcAddress(h, 'GetMyTime');
        if Assigned(func) then
          ShowMessage(FormatDatetime('yyyy-mm-dd hh:nn:ss', func));
        FreeLibrary(h);
      end;
    end;
  end; //dOpen.execute
end;

有人嘗試過類似的東西嗎?

避免從項目管理器樹的“包含”節點中刪除單元-Delphi 10和10.1都崩潰...


編輯1:它在某些條件下工作

感謝大衛的回答,我設法取得了一些進展:
當相關的內容

or subfolders is either in the folder where the application and the test BPL are or in relevant or folder. 子文件夾位於應用程序和測試BPL所在的文件夾中,或者位於相關的文件夾中。

如果沒有上述條件,盡管我倆都無法
and
were in the %PATH% Environment variable. 位於%PATH%環境變量中。 它沒有找到RTL軟件包。


如果應用程序依賴於%PATH%變量來查找必要的BPL,則有一個容易解釋的副作用。 因為我有C:\\ Windows \\ SysWOW64; C:\\ WINDOWS \\ system32; C:\\ WINDOWS
在%PATH%變量中,如果我使用運行時程序包為Win32平台編譯,則會收到以下錯誤消息:
應用程序無法正確啟動(0xc000007b)
這是因為32位應用程序嘗試加載64位BPL。

我可以輕松地交換System32和SysWOW64的位置,但這是全局變量,而不是用戶路徑變量,並且需要重新啟動才能使更改生效。
" BPLs into the platform output folder. 我將繼續進行試驗,但是到目前為止,唯一可行的解​​決方案是將使用過的“ ” BPL保留在平台輸出文件夾中。

異常文本指示對LoadLibrary的調用失敗,並且GetLastError返回ERROR_MOD_NOT_FOUND 對此有兩種常見的解釋:

  1. DLL搜索找不到包文件。 可能是名稱錯誤,或者程序包不在DLL搜索算法搜索的位置。
  2. 可以找到該軟件包文件,但是找不到其依賴項之一。 例如,也許找不到rtl包。

使用Dependency Walker調試問題。 在配置文件模式下使用它,它將告訴您找不到哪個模塊。

暫無
暫無

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

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