我想在Delphi 10 Seattle(Update 1)或Delphi 10.1 Berlin项目(Enterprise版本)中动态加载BPL模块。但是LoadPackage函数失败并显示消息(在32位和64位目标平台上):
Project LoadPackageTest.exe引发了异常类EPackageError,其中包含消息'无法在此处加载包"实际路径" \ TestBplPackage.bpl。 无法找到指定的模块'
我的开发平台是Windows 10 Pro 64位。
我确信传递的文件名是正确的(它包含完整路径)。 我到目前为止做了什么:
如果使用Delphi 2007 Enterprise编译,同一个项目组没有问题(我必须从头开始重新创建) - 在同一台Win 10 PC上
如果我加载标准.DLL - 它已正确加载,我可以在D2007,D10和D10.1中调用函数(适用于D10和D10.1上的32位和64位目标)。
实际上,LoadPackage调用SafeLoadLibrary,它调用LoadLibrary(所有这些过程都在System.SysUtils中。
我使用和不使用Run Time包编译了测试可执行文件 有代码:
library TestDLL;
uses SysUtils, Classes;
{$R *.res}
function GetMyTime: TDateTime; stdcall;
begin
Result:= Now;
end;
exports GetMyTime;
end.
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.
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崩溃......
感谢大卫的回答,我设法取得了一些进展:
当相关内容相符时,它能正常工作
C:\ Program Files(x86)\ Embarcadero \ Studio \ 18.0 \ Redist \
Win32 或 Win64 子文件夹位于应用程序和测试BPL所在的文件夹中,或者位于相关的 System32 或 SysWOW64 文件夹。
如果没有上述内容,尽管两者都存在,但我无法使其发挥作用
C:\ Program Files(x86)\ Embarcadero \ Studio \ 18.0 \ bin 和
C:\ Program Files(x86)\ Embarcadero \ Studio \ 18.0 \ bin64
在%PATH%环境变量中。它没有找到 RTL 包。
如果应用程序依赖%PATH%变量来查找必要的BPL,则会有一个易于解释的副作用。因为我有C:\ Windows \ SysWOW64; C:\ WINDOWS \ system32; C:\ WINDOWS
在%PATH%变量中,如果我使用运行时包编译Win32平台,我会收到以下错误消息:
应用程序无法正确启动(0xc000007b)
这是因为32位应用程序试图加载64位BPL。
我可以轻松交换System32和SysWOW64的位置,但这是全局的,而不是用户路径变量,需要重新启动才能使更改生效。
我将继续进行实验,但到目前为止,唯一100%可行的解决方案是保持使用的" 标准 " BPL进入平台输出文件夹。
答案 0 :(得分:4)
异常文字表示对LoadLibrary
的调用失败,GetLastError
返回ERROR_MOD_NOT_FOUND
。对此有两种常见的解释:
rtl
包。使用Dependency Walker调试问题。在配置文件模式下使用它,它将告诉您无法找到哪个模块。