¿Cómo verificar una DLL si existe una función?

Estoy trabajando en algo que carga dinámicamente archivos DLL especialmente formulados. Necesito poder verificar la DLL y asegurarme de que existan todas las funciones esperadas antes de considerar usar esta DLL. Si le faltan algunas funciones determinadas, no debería intentar cargarlo. Sé que podría intentar llamar a una de las funciones y ver si hay una excepción, pero vería errores en el modo de depuración.

¿Cómo debo verificar una DLL si existe una función? Me gustaría comprobarloantes d Lo cargo (usandoLoadLibrary) pero supongo que está bien si tengo que cargarlo para realizar esta verificación también.

ACTUALIZA

Acepté la respuesta de David a continuación y pensé en publicar mi código final para mostrar todo el proceso. Lo convertí en una función que devuelve un Bool, ya sea que haya tenido éxito o no, limpié un poco el código y agregué otra función en la parte inferior que usa esta para verificar cada nombre uno por uno.

Decidí usar este método en lugar de leerGetProcAddress porque me ayudará en el futuro con otras cosas.

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;