我已将这两种方法添加到我的Delphi 5应用程序的第一个单元中。
function Inp(PortAddress: Integer): Integer; stdcall; external 'inpout32.dll' name 'Inp32';
procedure Output(PortAddress, Value: Integer); stdcall; external 'inpout32.dll' name 'Out32';
但是,除非他们明确需要,否则我不想使用该软件发布inpout32库。目前程序在执行时会显示“Not Found”,除非它们出现在根目录或System32中。
用户只有在设置了特定选项时才会调用这些方法,但在使用inpout库之前,不会从.ini文件中收集这些方法。
有没有办法只在某些组件需要时才使用这个库,而不是按照我的方式声明它?
答案 0 :(得分:16)
此工具称为delay loading,已在Delphi 2010中添加。
以您的代码为例,您可以像这样编写导入:
function Inp(PortAddress: Integer): Integer; stdcall;
external 'inpout32.dll' name 'Inp32' delayed;
仅在首次调用函数时才会执行对此外部函数的绑定。如果绑定失败,则在运行时引发异常。
如果您需要更精细的控制,可以使用SetDliNotifyHook
和SetDliFailureHook
来自定义延迟加载行为。
一些博客文章补充产品文档:
在旧版本的Delphi中,您可以使用LoadLibrary
和GetProcAddress
。或者,如果你想要一点点光滑,我可以衷心地推荐Hallvard Vassbotn的延迟加载等级,他描述了in this blog article。此代码包含调用LoadLibrary
和GetProcAddress
的所有样板,并且使用起来比新的Delphi 2010内置功能稍微麻烦。
我成功使用了Hallvard的图书馆多年。一个小问题是它不是线程安全的,所以如果多个线程同时尝试绑定到一个函数,那么代码就会失败。通过向Hallvard的代码添加内部锁定,这很容易解决。
答案 1 :(得分:15)
在2010年之前的Delphi版本中,您必须使用经典的动态加载。考虑一下从Kernel32.dll
调用Beep
函数的典型(和简单)示例(当然,你应该不在实际代码中硬编码路径!):
type
TBeepFunc = function(dwFreq: DWORD; dwDuration: DWORD): BOOL; stdcall;
procedure TForm4.FormClick(Sender: TObject);
var
lib: HMODULE;
prc: TBeepFunc;
begin
lib := LoadLibrary('C:\WINDOWS\System32\Kernel32.dll');
if lib = 0 then RaiseLastOSError;
try
@prc := GetProcAddress(lib, 'Beep');
if Assigned(prc) then
prc(400, 2000)
else
ShowMessage('WTF? No Beep in Kernel32.dll?!');
finally
FreeLibrary(lib);
end;
end;