Delphi SHGetFolderPath和null终止字符串

bas*_*han 0 delphi

我正在使用此函数来获取用户文件夹:

function LocalAppDataPath : string;
const
  SHGFP_TYPE_CURRENT = 0;
var
  path: array [0..MaxChar] of char;
begin
  SHGetFolderPath(0,CSIDL_LOCAL_APPDATA,0,SHGFP_TYPE_CURRENT,@path[0]);
  Result := StrPas(path);
end;
Run Code Online (Sandbox Code Playgroud)

它工作得很好.但是在我将这个lib添加到我的项目之后:OpenJpeg 这个函数返回的值是:C.看起来由于某种原因,"path"数组中的每个char都有#0,因此返回的字符串被截断了在开始时.

当我删除:OpenJpeg从我使用它一切都很好.

知道为什么会这样吗?

Dav*_*nan 7

在该OpenJpeg单元的最顶部找到此代码:

type
  Char = AnsiChar;
Run Code Online (Sandbox Code Playgroud)

因此,在Unicode Delphi中使用时,此单元是有毒的.当你Char在你的代码中使用时,你会期待一个WideChar但是这个邪恶类型的别名会使你感到困惑.

我的建议是修改库删除该类型别名和替换每次使用的CharAnsiChar.

如果你不想这样做,你可以完全限定CharSystem.Char,或者使用WideChar在代码中明确.但是,正如我所说,这个单位有毒,而且确实需要补救.

如果启用Typed-Checked Pointers编译器选项,编译器将阻止您在使用地址运算符时PAnsiChar将a 传递给期望a的函数PWideChar,反之亦然@.如果可能的话,最好在编译时找到你的错误.

您可以通过path代替来简化代码@path[0].

请不要使用StrPas.它早已被弃用了.你可以简单地写

Result := path;
Run Code Online (Sandbox Code Playgroud)

该数组比所需的长一个字符.也就是说,假设MaxChar是我认为的那样.无论如何,数组应该是

path: array [0..MAX_PATH-1] of char;
Run Code Online (Sandbox Code Playgroud)

您也无法对API调用执行任何错误检查.请按照文档中的说明检查错误.

  • 你不需要`@`地址运算符.用`path`替换`@path [0]`,编译器仍会检测到任何类型不匹配错误. (2认同)