问题标签 [delphi-2009]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
1862 浏览

delphi - 为什么 TList.Remove() 会产生 EAccessViolation 错误?

为什么在执行下面的代码时会引发 EAccessViolation?

0 投票
1 回答
24645 浏览

delphi - 如何获得 TWinControl 的 X、Y 位置(相对于屏幕)

我试图在 TWinControl 中显示自定义提示,但我不知道如何获得它的位置。

使用位置 0,0 会在我的屏幕顶部(窗口外)显示提示,所以我猜它一定是屏幕上控件的位置。

编辑:

我找到了返回我期望的 TControl 属性 ClientOrigin,使用 ClientOrigin.X 和 ClientOrigin.Y 是否正确?

0 投票
3 回答
1992 浏览

delphi - 将启用 unicode 的 Delphi 2006 应用程序移植到 Delphi 2009

我有一个在 Delphi 2006 中完全兼容 unicode 的应用程序。我已将所有 AnsiStrings 替换为 WideStrings,将所有 VCL 控件替换为 TNT 控件,并将所有字符串函数从 AnsiStrings 更改为 WideStrings。看起来所有这些工作都是徒劳的,因为我将不得不扭转这一切。有没有办法让 Delphi 2009 认为 Widestrings 实际上是 UnicodeStrings?

0 投票
10 回答
3927 浏览

delphi - 升级到 D2009(Unicode 除外)的主要动机是什么?

在开发工具方面,我是一个犹豫不决的升级者。对于我大约一半的产品,我仍然使用 D7,而对于其他产品,我仍然使用 D2006。

事实是,虽然 Unicode 支持非常受欢迎并且非常有用,但它可能给我带来的麻烦多于我当前项目的收益(它们或多或少已经准备好 Unicode)。如果每个字符串占用的内存是以前的两倍,那么其中一个性能会受到很大影响的情况尤其如此。

那么,除了 Unicode,还有哪些其他主要的升级激励措施?

0 投票
2 回答
2279 浏览

xml - 如何使用 Delphi 2009 安装 nativeXML?

我用的是Delphi 2009,想操作一些XML数据。我听说 nativeXML 是最方便的方法之一。那么我该如何安装这个库呢?

0 投票
8 回答
5340 浏览

delphi - 为什么 Delphi 中的字符串内存过多?

我正在阅读一个包含 140 万行、大小为 24 MB(平均每行 17 个字符)的大型文本文件。

我使用的是 Delphi 2009,文件是 ANSI,但在读取时会转换为 Unicode,因此您可以说转换后的文本大小为 48 MB。

(编辑:我发现了一个更简单的例子......)

我将此文本加载到一个简单的 StringList 中:

我发现这些数据行似乎比它们的 48 MB 占用更多的内存。

事实上,它们使用 155 MB 内存。

我不介意 Delphi 使用 48 MB 甚至高达 60 MB 的内存管理开销。但是 155 MB 似乎过多。

这不是 StringList 的错。我之前尝试将这些行加载到记录结构中,并且得到了相同的结果(160 MB)。

我没有看到或理解是什么导致 Delphi 或 FastMM 内存管理器使用 3 倍于存储字符串所需的内存量。堆分配不可能那么低效,不是吗?

我已经对此进行了调试并尽可能地对其进行了研究。任何关于为什么会发生这种情况的想法,或者可能帮助我减少过度使用的想法将不胜感激。

注意:我以这个“较小”的文件为例。我真的想加载一个 320 MB 的文件,但 Delphi 要求超过 2 GB 的 RAM 并且由于这个多余的字符串要求而耗尽内存。

附录:Marco Cantu 刚刚发表了一份关于 Delphi 和 Unicode 的白皮书。Delphi 2009 将每个字符串的开销从 8 个字节增加到 12 个字节(对于指向字符串的实际指针,可能还要增加 4 个字节)。每 17x2 = 34 字节的行额外增加 16 字节几乎增加了 50%。但我看到超过 200% 的开销。额外的 150% 可能是什么?


成功!!感谢大家的建议。你们都让我思考。但我必须感谢 Jan Goyvaerts 的回答,因为他问:

...你为什么要使用 TStringList?文件真的必须作为单独的行存储在内存中吗?

这使我找到了一个解决方案,即我可以将我的行分组到我的程序知道的自然组中,而不是将 24 MB 文件作为 140 万行 StringList 加载。因此,这导致将 127,000 行加载到字符串列表中。

现在每行平均 190 个字符而不是 17 个。每个 StringList 行的开销是相同的,但现在行数要少得多。

当我将此应用到 320 MB 文件时,它不再耗尽内存,现在加载不到 1 GB 的 RAM。(而且加载只需要大约 10 秒,相当不错!)

解析分组的行会有一点额外的处理,但在每个组的实时处理中应该不明显。

(如果您想知道,这是一个家谱程序,这可能是我需要让它在不到 30 秒的时间内将大约 100 万人的所有数据加载到 32 位地址空间中的最后一步。所以我我们仍然有 20 秒的缓冲时间来将索引添加到数据中,这将需要允许显示和编辑数据。)

0 投票
1 回答
4010 浏览

delphi - 如何声明 TDictionary 枚举器?

我有一个 TDictionary 存储一堆按名称索引的对象,我希望能够检查所有对象。所以我尝试了这个:

但这不会编译。“不兼容的类型:‘TMyObject’和‘TPair’

所以我尝试了一些不同的方法:

那也没有编译。这个错误信息更奇怪:不兼容的类型:'TPair'和'TPair'

所以显然我需要某种时髦的语法来用for .. in循环枚举我的字典。有人知道如何正确申报吗?

编辑:Fabio Gomes 给出了一个可以正常工作的示例,但我的代码仍然无法使用他的方法进行编译。也许是因为我在不同的单位工作?字典和它用于 Value 端的类都定义在一个单元中,而这段代码在别处。这是否使它成为编译器中的错误?任何人都可以验证这一点吗?

编辑2:发现问题。 http://qc.embarcadero.com/wc/qcmain.aspx?d=69461如果有人感兴趣的话。

0 投票
5 回答
9915 浏览

delphi - 为什么 CharInSet 比 Case 语句快?

我很困惑。今天在 CodeRage,Marco Cantu 说 CharInSet 很慢,我应该尝试使用 Case 语句。我在我的解析器中这样做了,然后用 AQTime 检查了加速是什么。我发现 Case 语句要慢得多。

4,894,539 次处决:

而不是 CharInSet (P^, [' ', #10,#13, #0]) 做 inc(P);

时间为 0.25 秒。

但相同数量的执行:

而 True do
  case P^ of
    ' ', #10, #13, #0: break;
    其他公司(P);
  结尾;

“while True”需要 0.16 秒,第一种情况需要 0.80 秒,else 情况需要 0.13 秒,总共需要 1.09 秒,或超过 4 倍。

CharInSet 语句的汇编代码是:

add edi,$02
mov edx,$0064b290
movzx eax,[edi]
call CharInSet
test a1,a1
jz $00649f18(回到add语句)

而案例逻辑就是这样:

movzx eax,[edi]
sub ax,$01
jb $00649ef0
sub ax,$09
jz $00649ef0
sub ax,$03
jz $00649ef0
add edi,$02
jmp $00649ed6(回到 movzx 语句)

在我看来,案例逻辑使用了非常高效的汇编程序,而 CharInSet 语句实际上必须调用 CharInSet 函数,该函数位于 SysUtils 中,也很简单,即:

函数 CharInSet(C: AnsiChar; const CharSet: TSysCharSet): 布尔值;
开始
Result := C in CharSet;
结尾;

我认为这样做的唯一原因是因为 [' ', #10, #13, #0] 中的 P^ 在 Delphi 2009 中不再允许,因此调用会转换类型以允许它。

尽管如此,我对此感到非常惊讶,但仍然不相信我的结果。

AQTime 测量是否有问题,我是否在比较中遗漏了什么,或者 CharInSet 真的是一个值得使用的高效函数?


结论:

我想你明白了,巴里。感谢您抽出宝贵时间做详细的示例。我在我的机器上测试了你的代码,得到了 0.171、0.066 和 0.052 秒(我猜我的台式机比你的笔记本电脑快一点)。

在 AQTime 中测试该代码,它给出了:三个测试的 0.79、1.57 和 1.46 秒。在那里,您可以看到仪器的大量开销。但真正让我吃惊的是,这种开销将明显的“最佳”结果更改为实际上是最差的 CharInSet 函数。

所以 Marcu 是正确的,而 CharInSet 更慢。但是您无意中(或者可能是故意)通过提取 CharInSet 对 Set 方法中的 AnsiChar(P^) 所做的事情,给了我一个更好的方法。除了与 case 方法相比速度稍有优势之外,它还比使用 case 方法更少的代码和更易于理解。

您还让我意识到使用 AQTime(和其他检测分析器)进行错误优化的可能性。知道这一点将有助于我对 Delphi 的 Profiler 和内存分析工具做出决定,这也是对我的问题AQTime 如何做到这一点的另一个答案?. 当然,AQTime 在检测时不会更改代码,因此它必须使用其他魔法来完成。

所以答案是 AQTime 显示的结果会导致错误的结论。


跟进:我留下了这个问题,“指责”AQTime 结果可能具有误导性。但公平地说,我应该指导您阅读这个问题:Delphi 是否有快速 GetToken 例程?它开始认为 AQTime 给出了误导性的结果,并得出结论认为它没有。

0 投票
2 回答
4250 浏览

delphi - 我可以使用 Delphi 或 C++Builder 进行 Windows Mobile 6.1 开发吗?

我很好奇为移动设备(Windows Mobile 6.1)编程需要什么,以及是否可以使用我们已经习惯的 IDE(RAD Studio 2009)。

是否有一个移动开发社区可供 Delphi 或 C++Builder 用户学习?

开发技术是否存在差异,例如:驱动程序、内存限制、设备特定注意事项等?

文档和教程的链接总是很棒!

谢谢!

0 投票
2 回答
8026 浏览

delphi - 在 Delphi 2009 中将整数值转换为 AnsiString

IntToStr()函数返回现在是 Unicode 的字符串。我想转换为AnsiString. 我可以AnsiString(IntToStr(I))安全使用吗?