Delphi 10.3 函数 CharUpper 和 CharUpperW 不同 Delphi 10.4

标签 delphi

有人知道原因CharUpperCharUpperW Delphi 10.3 中的声明与 Delphi 10.4 中的不同。
Delphi 10.3 中的正确声明

    var
      chr   :WideChar;
    begin      
      chr := WideChar(CharUpperW(PWideChar('a'))); //chr = 'A'
//    chr := WideChar(CharUpperW(WideChar('a')));  //raise exeption: "access violation...
Delphi 10.4 中的正确声明
    var
      chr   :WideChar;
    begin   
//    chr := WideChar(CharUpperW(PWideChar('a')));  //raise exeption: "access violation...
      chr := WideChar(CharUpperW(WideChar('a')));   //chr = 'A'
编辑 :Remy Lebeau 的解释对 PWideChar 是正确的,但 Delphi 10.4 版和更早版本仍然存在差异!
勒博解释代码示例在10.4及更早版本编译,但函数输出不同。 10.4 之前的所有版本都得到正确的输出“A”!
var
  char , chr : WideChar;
begin
  chr := 'a';
  char := WideChar(CharUpperW(PWideChar(chr)));
end;
10.4 下的此示例无法正确输出是随机字符。
而且当然...
函数声明CharUpperW它在德尔福的船版中相同。
LPWSTR = PWideChar; 
function CharUpperW(lpsz: LPWSTR): LPWSTR; stdcall;**
编辑:在 10.4 下添加反汇编代码
umCommon.pas.114: chr := 'a';
0064C52C 66BB6100         mov bx,$0061
umCommon.pas.115: char := WideChar(CharUpperW(PWideChar(chr)));
0064C530 8D45FC           lea eax,[ebp-$04]
0064C533 8BD3             mov edx,ebx
0064C535 E8EEE7DBFF       call @UStrFromWChar
0064C53A 8B45FC           mov eax,[ebp-$04]
0064C53D E8C2E7DBFF       call @UStrToPWChar
0064C542 50               push eax
0064C543 E8809DDCFF       call CharUpperW
10.3下的反汇编代码
umCommon.pas.114: chr := 'a';
0063A905 66BB6100         mov bx,$0061
umCommon.pas.115: char := WideChar(CharUpperW(PWideChar(chr)));
0063A909 0FB7C3           movzx eax,bx
0063A90C 50               push eax
0063A90D E8AAB1DDFF       call CharUpperW

最佳答案

Win32 CharUpperW()函数不带单WideChar作为输入,只有一个 PWideChar .但是该指针的解释取决于其高位字是零(低位字包含单个字符)还是非零(整个指针指向以空字符结尾的字符串)。
唯一的办法就是CharUpperW(WideChar('a'))甚至可以在任何版本中编译,前提是 Embarcadero 添加了自己的重载,该重载需要单个 WideChar作为输入(我没有安装任何 10.x 版本来验证)。
恕我直言,CharUpperW()由于滥用指针,使用起来有点危险。我不会相信它具有类型转换的文字,而是使用一个变量,这样你就可以确保你给它的正是它真正想要的:

var
  chr : array[0..1] of WideChar;
begin
  chr[0] := 'a';
  chr[1] := #0;
  CharUpperW(chr);
end;
var
  chr : WideChar;
begin
  chr := 'a';
  char := WideChar(CharUpperW(PWideChar(chr)));
end;
话虽如此,RTL 中还有其他函数来处理此任务,请改用这些函数。
更新:我为此创建了一个支持票:
RSP-31498: Bad codegen breaks Winapi.Windows.CharUpperW()

关于Delphi 10.3 函数 CharUpper 和 CharUpperW 不同 Delphi 10.4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64627885/

相关文章:

delphi - 我什么时候应该添加对 Delphi 项目的文件引用?

delphi - Delphi 11 Alexandria 中的组件图标

delphi - 如何向项目添加新的(自制)单元

delphi - TWebBrowser 如何在 IE8 上将插入符位置设置为 INPUT(text) 字段的末尾

D2007 与 DXE2 中的 Delphi HDC 类型声明

delphi - TRttiField - 如何转换类(class)

delphi - 如何访问不受支持的 UI 元素?

Delphi错误E2010不兼容的类型: 'string' and 'procedure, untyped pointer or untyped parameter'

delphi - 没有可以使用这些参数调用的 'SendMsg' 的重载版本

delphi - 与 TControl 的父/子关系