这看起来很简单,但下面的代码不起作用。
BPL:
procedure DoSomething();
begin
LogEvent('Did');
end;
exports
DoSomething;
主EXE:
procedure CallModuleFunc;
var
H: THandle;
P: procedure();
begin
H := LoadPackage('mymod.bpl');
try
if (H <> 0) then
begin
@P := GetProcAddress(H, 'DoSomething');
if Assigned(P) then
P();
end;
finally
UnloadPackage(H);
end;
end;
现在没有错误了,bpl成功加载了LoadPackage()
,但是GetProcAddress()
返回nil。为什么呢?可能是因为名字乱了。我尝试添加stdcall
(导出函数和P
的声明),但这并没有解决问题。我在网上看到了数百个例子,它应该是这样工作的。我甚至试过GetProcAddress(H, 'DoSomething$qqsv')
,但它也不工作。我错过了什么?
4条答案
按热度按时间yduiuuwa1#
经过几个小时的搜索和尝试和错误,我意识到这必须是关于我做的事情或做得不同。问题是我的mymod.bpl的第一个版本被放到了 Delphi 的默认BPL输出目录中(没有导出,根本没有DoSomething())。然后,我将BPL输出目录更改为项目的源代码根目录,这样我就可以在一个地方看到源代码和bpl模块。exe没有像以前在 Delphi 7中那样放在源代码所在的位置,而是放在“安装”或“发布”文件夹下。误导我的是,当LoadPackage()无法在exe的当前目录中找到模块时(该目录为“已发布/已发布”),它会查看 Delphi 的默认包文件夹(该文件夹中有bpl的第一个错误版本)并加载它,因此那里没有错误,但也没有DoSomething(),因为它不再被我的模块编译更新。
我希望这个解释能帮助其他可能有类似问题的人弄清楚事情。感谢所有花时间阅读本文并发表评论的人。
lnlaulya2#
也许太晚了,但我想提出我的解决方案,这取决于ChatGPT提示:
首先,你必须打开一个新的BPL项目。然后你可以在BPLUnit.pas(class'es,Function's,Procedure's,...)中编写代码。对于这一点,最好的做法是,写一个“接口”。接口不支持构造函数、析构函数、虚函数、抽象函数和过程)。
这里是 Delphi 的代码,它展示了如何对界面单元进行编码:
下面是接口实现代码(BPL项目代码):
现在,您可以使用接口(在EXE项目中):
有了这个代码,你不需要使用“导出”关键字。
希望我能帮上忙。
vatpfxk53#
下面是一段代码。它运行在 Delphi XE3下。
单位Unit1.pas
测试BPL的项目。只包含一个带有一个TButton的Tform。(Package1.bpl与project1.exe在同一目录中)
cczfrluj4#
您必须在声明中添加stdCall。