我对 Delphi 10.2 Pascal 编程语言中的特定编程问题有疑问。
StringOfChar 和 FillChar 在 2012 年之前发布的 CPU 上的 Win64 版本构建下无法正常工作。
FillChar 的预期结果只是在给定内存缓冲区中重复 8 位字符的普通序列。
StringOfChar 的预期结果相同,但结果存储在字符串类型中。
但实际上,当我使用 10.2 版本的 Delphi 编译在 10.2 之前的 Delphi 中运行的应用程序时,我们为 Win64 编译的应用程序在 2012 年之前发布的 CPU 上无法正常运行。
StringOfChar 和 FillChar 不能正常工作——它们返回一个由不同字符组成的字符串,尽管是重复的模式——而不是它们应该返回的相同字符的序列。
这是足以说明问题的最少代码。请注意,序列的长度应至少为 16 个字符,且字符不应为 nul (#0)。代码如下:
procedure TestStringOfChar;
var
a: AnsiString;
ac: AnsiChar;
begin
ac := #1;
a := StringOfChar(ac, 43);
if a <> #1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1 then
begin
raise Exception.Create('ANSI StringOfChar Failed!!');
end;
end;
我知道 StackOverflow 上有很多 Delphi 程序员。您遇到同样的问题吗?如果是,你是如何解决的?解决办法是什么?顺便说一下,I have contacted the developers of Delphi but they didn’t confirm nor deny the issue so far .我使用的是 Embarcadero Delphi 10.2 版本 25.0.26309.314。
更新:
如果您的 CPU 是 2012 年或之后生产的,请在调用 StringOfChar 重现问题之前添加以下行:
const
ERMSBBit = 1 shl 9; //$0200
begin
CPUIDTable[7].EBX := CPUIDTable[7].EBX and not ERMSBBit;
关于April 2017 RAD Studio 10.2 Hotfix for Toolchain Issues - 尝试过使用它和不使用它 - 它没有帮助。无论修补程序如何,该问题都存在。
更新#2
Embarcadero 已于 08/Aug/17 下午 6:03 确认并解决了此问题。因此,在 Delphi 10.2 Tokyo Release 1(2017 年 8 月 8 日发布)中修复了此错误。
最佳答案
StringOfChar(A: AnsiChar, count) 在底层使用 FillChar。
您可以使用以下代码来解决问题:
(*******************************************************
System.FastSystem
A fast drop-in addition to speed up function in system.pas
It should compile and run in XE2 and beyond.
Alpha version 0.5, fully tested in Win64
(c) Copyright 2016 J. Bontes
This Source Code Form is subject to the terms of the
Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file,
You can obtain one at http://mozilla.org/MPL/2.0/.
********************************************************
FillChar code is an altered version FillCharsse2 SynCommons.pas
which is part of Synopse framework by Arnaud Bouchez
********************************************************
Changelog
0.5 Initial version:
********************************************************)
unit FastSystem;
interface
procedure FillChar(var Dest; Count: NativeInt; Value: ansichar); inline; overload;
procedure FillChar(var Dest; Count: NativeInt; Value: Byte); overload;
procedure FillMemory(Destination: Pointer; Length: NativeUInt; Fill: Byte); inline;
{$EXTERNALSYM FillMemory}
procedure ZeroMemory(Destination: Pointer; Length: NativeUInt); inline;
{$EXTERNALSYM ZeroMemory}
implementation
procedure FillChar(var Dest; Count: NativeInt; Value: ansichar); inline; overload;
begin
FillChar(Dest, Count, byte(Value));
end;
procedure FillMemory(Destination: Pointer; Length: NativeUInt; Fill: Byte);
begin
FillChar(Destination^, Length, Fill);
end;
procedure ZeroMemory(Destination: Pointer; Length: NativeUInt); inline;
begin
FillChar(Destination^, Length, 0);
end;
//This code is 3x faster than System.FillChar on x64.
{$ifdef CPUX64}
procedure FillChar(var Dest; Count: NativeInt; Value: Byte);
//rcx = dest
//rdx=count
//r8b=value
asm
.noframe
.align 16
movzx r8,r8b //There's no need to optimize for count <= 3
mov rax,$0101010101010101
mov r9d,edx
imul rax,r8 //fill rax with value.
cmp rdx,59 //Use simple code for small blocks.
jl @Below32
@Above32: mov r11,rcx
mov r8b,7 //code shrink to help alignment.
lea r9,[rcx+rdx] //r9=end of array
sub rdx,8
rep mov [rcx],rax
add rcx,8
and r11,r8 //and 7 See if dest is aligned
jz @tail
@NotAligned: xor rcx,r11 //align dest
lea rdx,[rdx+r11]
@tail: test r9,r8 //and 7 is tail aligned?
jz @alignOK
@tailwrite: mov [r9-8],rax //no, we need to do a tail write
and r9,r8 //and 7
sub rdx,r9 //dec(count, tailcount)
@alignOK: mov r10,rdx
and edx,(32+16+8) //count the partial iterations of the loop
mov r8b,64 //code shrink to help alignment.
mov r9,rdx
jz @Initloop64
@partialloop: shr r9,1 //every instruction is 4 bytes
lea r11,[rip + @partial +(4*7)] //start at the end of the loop
sub r11,r9 //step back as needed
add rcx,rdx //add the partial loop count to dest
cmp r10,r8 //do we need to do more loops?
jmp r11 //do a partial loop
@Initloop64: shr r10,6 //any work left?
jz @done //no, return
mov rdx,r10
shr r10,(19-6) //use non-temporal move for > 512kb
jnz @InitFillHuge
@Doloop64: add rcx,r8
dec edx
mov [rcx-64+00H],rax
mov [rcx-64+08H],rax
mov [rcx-64+10H],rax
mov [rcx-64+18H],rax
mov [rcx-64+20H],rax
mov [rcx-64+28H],rax
mov [rcx-64+30H],rax
mov [rcx-64+38H],rax
jnz @DoLoop64
@done: rep ret
//db $66,$66,$0f,$1f,$44,$00,$00 //nop7
@partial: mov [rcx-64+08H],rax
mov [rcx-64+10H],rax
mov [rcx-64+18H],rax
mov [rcx-64+20H],rax
mov [rcx-64+28H],rax
mov [rcx-64+30H],rax
mov [rcx-64+38H],rax
jge @Initloop64 //are we done with all loops?
rep ret
db $0F,$1F,$40,$00
@InitFillHuge:
@FillHuge: add rcx,r8
dec rdx
db $48,$0F,$C3,$41,$C0 // movnti [rcx-64+00H],rax
db $48,$0F,$C3,$41,$C8 // movnti [rcx-64+08H],rax
db $48,$0F,$C3,$41,$D0 // movnti [rcx-64+10H],rax
db $48,$0F,$C3,$41,$D8 // movnti [rcx-64+18H],rax
db $48,$0F,$C3,$41,$E0 // movnti [rcx-64+20H],rax
db $48,$0F,$C3,$41,$E8 // movnti [rcx-64+28H],rax
db $48,$0F,$C3,$41,$F0 // movnti [rcx-64+30H],rax
db $48,$0F,$C3,$41,$F8 // movnti [rcx-64+38H],rax
jnz @FillHuge
@donefillhuge:mfence
rep ret
db $0F,$1F,$44,$00,$00 //db $0F,$1F,$40,$00
@Below32: and r9d,not(3)
jz @SizeIs3
@FillTail: sub edx,4
lea r10,[rip + @SmallFill + (15*4)]
sub r10,r9
jmp r10
@SmallFill: rep mov [rcx+56], eax
rep mov [rcx+52], eax
rep mov [rcx+48], eax
rep mov [rcx+44], eax
rep mov [rcx+40], eax
rep mov [rcx+36], eax
rep mov [rcx+32], eax
rep mov [rcx+28], eax
rep mov [rcx+24], eax
rep mov [rcx+20], eax
rep mov [rcx+16], eax
rep mov [rcx+12], eax
rep mov [rcx+08], eax
rep mov [rcx+04], eax
mov [rcx],eax
@Fallthough: mov [rcx+rdx],eax //unaligned write to fix up tail
rep ret
@SizeIs3: shl edx,2 //r9 <= 3 r9*4
lea r10,[rip + @do3 + (4*3)]
sub r10,rdx
jmp r10
@do3: rep mov [rcx+2],al
@do2: mov [rcx],ax
ret
@do1: mov [rcx],al
rep ret
@do0: rep ret
end;
{$endif}
解决问题的最简单方法是 Download Mormot并包括 SynCommon.pas进入你的项目。这会将 System.FillChar 修补到上述代码,并包括一些其他性能改进。
请注意,您不需要所有的 Mormot,只需要 SynCommons 本身。
关于windows - Delphi 10.2 for Win64 Release Target 下的 FillChar 和 StringOfChar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43958955/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解
我在安装“redcarpet”gem时遇到以下错误。它在我friend的机器上安装没有问题。(我想安装它来运行yard)ruby版本:1.9.3命令输出:D:\Learning\Common_POM_FW\SampleProjects>yard[error]:Missing'redcarpet'gemforMarkdownformatting.Installitwith`geminstallredcarpet`D:\Learning\Common_POM_FW\SampleProjects>geminstallredcarpetTemporarilyenhancingPATHtoinc
我们正在开发一个需要推送通知的WP8应用程序。为了测试它,我们使用CURL命令行运行推送通知POST请求,确保它实际连接,使用客户端SSL证书进行身份验证并发送正确的数据。我们确实知道,当我们收到对设备的推送时,这项工作是有效的。这是我们一直用于测试目的的CURL命令:curl--certclient_cert.pem-v-H"Content-Type:text/xml"-H"X-WindowsPhone-Target:Toast"-H"X-NotificationClass:2"-XPOST-d"MytitleMysubtitle"https://db3.notify.live.ne
我在Windows7上运行Jekyll时遇到问题。当我运行时jekyll出现以下错误C:\temp\jekyll\kouphax.github.com>jekyllConfigurationfromC:/temp/jekyll/kouphax.github.com/_config.ymlBuildingsite:C:/temp/jekyll/kouphax.github.com->C:/temp/jekyll/kouphax.github.com/_siteunit-testingYouaremissingalibraryrequiredforTextile.Pleaserun:$[s
我正在尝试使用本手册让Jekyll在Windows8x64上运行:RunningJekyllonWindows我正在使用来自rubyinstaller.org的以下两个下载:ruby2.0.0-p0(x64)DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe所以我根据手册设置了Ruby和DevKit(希望它是更新的版本)。我尝试运行一点HelloWorld.rb脚本,它工作正常,路径变量已设置。然后我尝试运行geminstalljekyll并得到以下输出:geminstalljekyll-outputonpastebin.com问题似乎出在名为f
在Windows上通过ruby2.0.0安装iconv时出错通过ruby2.0.0在Windows上安装iconv时出错我正在尝试安装iconv,但是当我运行以下命令时:geminstalliconv我的结果:TemporarilyenhancingPathtoincludeDevKit...Buildingnativeextensions.Thiscouldtakeawhile...Error:Errorinstallingiconv:ERROR:Failedtobuildgemnativeextension.C:/Ruby/Ruby200/bin/ruby.exe-r./s