Как проверить DLL, если функция существует?

Я работаю над тем, что динамически загружает специально сформулированные библиотеки DLL. Мне нужно иметь возможность проверить DLL и убедиться, что все ожидаемые функции существуют, прежде чем я рассмотрю возможность использования этой DLL. Если в нем отсутствуют некоторые определенные функции, я не должен пытаться загрузить его. Я знаю, что могу попытаться вызвать одну из функций и посмотреть, есть ли исключение, но я вижу ошибки в режиме отладки.

Как я должен идти о проверке 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;

Ответы на вопрос(2)

Ваш ответ на вопрос