Почему SHParseDisplayName выдает нарушение прав доступа, если я импортировал его сам? - PullRequest
5 голосов
/ 11 октября 2011

Я получаю нарушение прав доступа при попытке получить pidl-форму пути в Delphi, и возвращенный pidl равен nil. Это мой код:

type
  // TParseDisplayName = function(pszPath: PChar; pbc: pointer; var pidl: PItemIDList; sfgaoIn: LongWord; var psfgaoOut: LongWord): LongInt;
  TParseDisplayName = function(pszPath: PWideChar; pbc: IBindCtx; var pidl: PItemIDList; sfgaoIn: ULong; var psfgaoOut: ULong): HResult;

var
  SHParseDisplayName: TParseDisplayName;
  SHELL32DLLHandle : THandle;

procedure test();
var
  ws : WideString;
  tmpLongWord: ULong;
  lpItemID: PItemIDList;
begin
  //ws := 'Mes documents';

  CoInitialize(nil);

  // path to test
  ws := 'C:\inetsdk\Nouveau Document WordPad.doc';

  if (SHParseDisplayName(PWideChar(ws), nil, lpItemID, 0, tmpLongWord) = S_OK) then
    if not assigned(lpItemID) then      
      s := SysErrorMessage(getLastError);

  CoUnInitialize();
end;

initialization
  SHELL32DLLHandle  := LoadLibraryW('shell32.dll');

  @SHParseDisplayName := GetProcAddress(SHELL32DLLHandle, 'SHParseDisplayName');

1 Ответ

5 голосов
/ 11 октября 2011

Объявление TParseDisplayName опускает соглашение о вызовах. Вам необходимо включить stdcall.

TParseDisplayName = function(pszPath: PWideChar; pbc: IBindCtx; 
  var pidl: PItemIDList; sfgaoIn: ULong; var psfgaoOut: ULong): HResult; stdcall;

Когда вы не указываете соглашение о вызовах, используется соглашение о вызовах по умолчанию. Соглашение о вызовах по умолчанию register. Это имеет другую семантику для передачи параметров и очистки, что приводит к типу ошибки времени выполнения, которую вы испытали Практически все функции Windows API используются stdcall.

...