Winapi.ShLwApi.StrFormatByteSize64 将我的应用程序视为 DLL

Winapi.ShLwApi.StrFormatByteSize64 treats my app as a DLL

在 Delphi 10.4 中,尝试使用 Winapi.ShLwApi.StrFormatByteSize64Int64 文件大小值转换为格式化字符串时出现运行时错误:

var
  ThisSize: Int64;
  pszBuf: PWideChar;
  cchBuf: Cardinal;

Winapi.ShLwApi.StrFormatByteSize64(ThisSize, pszBuf, cchBuf);

错误信息:

--------------------------- MyApp.exe - Entry point not found
--------------------------- The Procedure Entry point "StrFormatByteSize64W" was not found in the DLL "C:\DELPHI\MyApp\Win32\Debug\MyApp.exe".
--------------------------- OK


如何解决这个问题?

remarks for the function in the documentation 说:

StrFormatByteSize64 can be used for either ANSI or Unicode characters. However, while StrFormatByteSize64A can be called directly, StrFormatByteSize64W is not defined. When StrFormatByteSize64 is called with a Unicode value, StrFormatByteSizeW is used.

Delphi 导入声明为:

function StrFormatByteSize64; external shlwapi32 name 'StrFormatByteSize64W';

换句话说,这是 Delphi RTL 中的翻译错误。函数 StrFormatByteSize64Wshlwapi.dll 中不存在。

如文档所述,改为调用 StrFormatByteSize。这是由 Windows 头文件为您处理的,但 Embarcadero 在翻译它们时没有发现这种细微差别。

本程序演示:

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.ShLwApi;

procedure Main;
var
  ThisSize: Int64;
  szBuf: array[0..255] of Char;
  cchBuf: Cardinal;
begin
  ThisSize := Int64(1024)*1024*1024*256;
  cchBuf := Length(szBuf);
  Winapi.ShLwApi.StrFormatByteSize(ThisSize, szBuf, cchBuf);
  Writeln(szBuf);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

输出:

256 GB

我已将此事报告给 Embarcadero:https://quality.embarcadero.com/browse/RSP-29943