Delphi Winapi.ShlObj.SHGetFolderPath的可再现错误

Delphi Winapi.ShlObj.SHGetFolderPath的可再现错误,delphi,winapi,delphi-10.1-berlin,delphi-10.2-tokyo,Delphi,Winapi,Delphi 10.1 Berlin,Delphi 10.2 Tokyo,使用此代码,我可以获得AV: uses Winapi.ShlObj; function GetUserAppDataPath: string; var ThisPath: PWideChar; begin if Winapi.ShlObj.SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, ThisPath) = S_OK then Result := string(ThisPath) else Re

使用此代码,我可以获得AV:

uses
  Winapi.ShlObj;

function GetUserAppDataPath: string;
var
  ThisPath: PWideChar;
begin
  if Winapi.ShlObj.SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, ThisPath) = S_OK then
    Result := string(ThisPath)
  else
    Result := '';
end;
在Delphi10.2 Tokyo中,如果我调用这个函数两次,第二次就会得到AV

是什么导致了这个错误

我使用PWideChar是因为Delphi IDE告诉我:

您没有遵守文档中列出的协议。最后一个论点的结论是

指向将接收路径的长度为MAX_PATH的以null结尾的字符串的指针

您需要分配该缓冲区并传递其地址

function GetUserAppDataPath: string;
var
  ThisPath: array[0..MAX_PATH-1] of Char;
begin
  if Winapi.ShlObj.SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, ThisPath) = S_OK then
    Result := ThisPath
  else
    Result := '';
end;

你为什么总是否决我的问题?没错!谁否决了这个问题?为什么?@dummzeuch可能是同一个人在解决方案下删除了我的评论谢谢你的解决方案!不加解释?我猜这是因为缺乏研究工作。在这种情况下,需要研究的是在函数名上按F1键。不,不是同一个。我知道这是事实,因为我删除了你的评论。答案是现成的:请不要对您的问题或答案添加评论以表示感谢。很难错过,因为所有字符都是粗体。我通常使用字符数组[0..MAX_PATH]来确定。如果字符串的长度为MAX_PATH,则终止零还需要一个字符。即使我解释错了,多加一个字符也无妨。@Rudy,你解释错了。我的答案中的代码足够了。我不知道这是不是真的。我将继续使用以前使用过的术语。术语长度通常用于描述字符数,不包括空终止符。术语大小通常用于表示缓冲区的大小(以字节为单位),包括空终止符。虽然MSDN在使用这些术语时并不一致,但我可能也会谨慎行事。FWIW,示例代码似乎建议缓冲区的大小必须为MAX_PATH确实:TCHAR szPath[MAX_PATH];。