【问题标题】:Why does SHParseDisplayName give an access violation if I've imported it myself?如果我自己导入了 SHParseDisplayName,为什么会出现访问冲突?
【发布时间】:2011-10-11 08:42:25
【问题描述】:

我在 Delphi 中尝试从路径获取 pidl 时遇到访问冲突,并且返回的 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');

【问题讨论】:

    标签: delphi winapi windows-shell


    【解决方案1】:

    TParseDisplayName 的声明省略了调用约定。您需要包含stdcall

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

    当您不指定调用约定时,将使用默认调用约定。默认调用约定是register。这对于参数传递和清理具有不同的语义,这会导致您遇到的运行时错误类型。几乎所有的 Windows API 函数都使用了stdcall

    【讨论】:

    • 非常感谢!非常感谢您的快速帮助大卫!
    • 我的跟踪投票者回来了。有趣的是,这个缠扰者只会成功地降低自己的声誉。
    • @Ken 实际上,闪电战确实让代表回来了。但是知道这里的事情是如何运作的当前跟踪者没有闪电战。
    • @David:这就是为什么拒绝投票会花费代表。除非一大群人反对,否则它是没有意义的。我发现很多非常好的答案都会得到 + 和 - 票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多