gpt4 book ai didi

delphi - 如何检查DLL中的函数是否存在?

转载 作者:行者123 更新时间:2023-12-03 15:03:35 24 4
gpt4 key购买 nike

我正在研究动态加载专门制定的 DLL 的东西。在考虑使用这个 DLL 之前,我需要能够检查 DLL 并确保所有预期的函数都存在。如果它缺少某些功能,我不应该尝试加载它。我知道我可以尝试调用其中一个函数并查看是否存在异常,但我会在 Debug模式下看到错误。

如果函数存在,我应该如何检查 DLL?我想在加载它之前检查它(使用 LoadLibrary),但我想如果我也必须加载它来执行此检查,那就没问题了。

更新

我已经接受了下面大卫的回答,并认为我应该发布我的最终代码来展示整个过程。我把它变成了一个返回 Bool 的函数,无论成功与否,稍微清理了一下代码,并在底部添加了另一个函数,该函数使用这个函数来逐一检查每个名称。

我决定使用此方法而不是阅读 GetProcAddress,因为它会对我将来处理其他事情有所帮助。

type
  PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
  PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;

function ImageNtHeader(Base: Pointer): PIMAGE_NT_HEADERS; stdcall;
external 'dbghelp.dll';
function ImageRvaToVa(NtHeaders: Pointer; Base: Pointer; Rva: ULONG;
LastRvaSection: Pointer): Pointer; stdcall; external 'dbghelp.dll';

function ExportedFunctionNames(const ImageName: string; NamesList: TStrings): Bool;
var
i: Integer;
FileHandle: THandle;
ImageHandle: THandle;
ImagePointer: Pointer;
Header: PIMAGE_NT_HEADERS;
ExportTable: PIMAGE_EXPORT_DIRECTORY;
NamesPointer: Pointer;
Names: PAnsiChar;
NamesDataLeft: Integer;
begin
Result:= False;
NamesList.Clear;
FileHandle:= CreateFile(PChar(ImageName), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if FileHandle = INVALID_HANDLE_VALUE then Exit;
try
ImageHandle:= CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if ImageHandle = 0 then Exit;
try
ImagePointer:= MapViewOfFile(ImageHandle, FILE_MAP_READ, 0, 0, 0);
if not Assigned(ImagePointer) then Exit;
try
Header:= ImageNtHeader(ImagePointer);
if not Assigned(Header) then Exit;
if Header.Signature <> $00004550 then Exit; // "PE\0\0" as a DWORD.
ExportTable:= ImageRvaToVa(Header, ImagePointer,
Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
if not Assigned(ExportTable) then Exit;
NamesPointer:= ImageRvaToVa(Header, ImagePointer,
Cardinal(ExportTable.AddressOfNames), nil);
if not Assigned(NamesPointer) then Exit;
Names:= ImageRvaToVa(Header, ImagePointer, Cardinal(NamesPointer^), nil);
if not Assigned(Names) then Exit;
NamesDataLeft:= Header.OptionalHeader.DataDirectory[0].Size;
for i:= 0 to ExportTable.NumberOfNames - 1 do begin
NamesList.Add(Names);
while (Names^ <> chr(0)) and (NamesDataLeft > 0) do begin
Inc(Names);
Dec(NamesDataLeft);
end;
Inc(Names);
end;
Result:= True;
finally
UnmapViewOfFile(ImagePointer);
end;
finally
CloseHandle(ImageHandle);
end;
finally
CloseHandle(FileHandle);
end;
end;

function IsMyDLL(const Filename: String): Bool;
var
H: THandle;
L: TStringList;
function InList(const Func: String): Bool;
begin
Result:= L.IndexOf(Func) >= 0;
end;
begin
Result:= False;
L:= TStringList.Create;
try
if ExportedFunctionNames(Filename, L) then begin
Result:=//Names of functions which need to exist
InList('GetName') and
InList('GetDescription') and
InList('GetVersion') and
InList('Start') and
InList('Stop');
end;
finally
L.Free;
end;
end;

最佳答案

您必须使用LoadLibrary,然后对要检查其存在性的每个函数使用GetProcAddress。确实没有其他合理的选择(除非有特定原因需要避免`LoadLibrary)。由于您的意图似乎只是检查函数是否存在,仅此而已,因此 LoadLibrary 和 GetProcAddress 是最简单的方法;您可以用很少的代码行完成所有工作,并且错误检查非常简单明了。

关于delphi - 如何检查DLL中的函数是否存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9576118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com