我正在尝试调试仅在我的大型应用程序(在 XE3 中运行良好)在使用 XE4 编译后运行时才出现的行为。这个问题似乎导致一些引用的字符串(例如“MyString”)即使在 Web.HTTPProd 中的 TPageProducer 被“取消引用”之后仍保留它们的引用。例如,考虑下面的代码,它是从这个 Delphi 源单元 Web.HTTPApp 的一小部分摘录:
procedure ExtractHeaderFields(Separators, _WhiteSpace: TSysCharSet; Content: PChar;
Strings: TStrings; Decode: Boolean; StripQuotes: Boolean = False);
{$ENDIF NEXTGEN}
var
Head, Tail: PChar;
EOS, InQuote, LeadQuote: Boolean;
QuoteChar: Char;
ExtractedField: string;
{$IFNDEF NEXTGEN}
WhiteSpaceWithCRLF: TSysCharSet;
SeparatorsWithCRLF: TSysCharSet;
{$ENDIF !NEXTGEN}
function DoStripQuotes(const S: string): string;
var
I: Integer;
InStripQuote: Boolean;
StripQuoteChar: Char;
begin
Result := S;
InStripQuote := False;
StripQuoteChar := #0;
if StripQuotes then
begin
for I := Result.Length - 1 downto 0 do
if Result.Chars[I].IsInArray(['''', '"']) then
if InStripQuote and (StripQuoteChar = Result.Chars[I]) then
begin
Result.Remove(I, 1);
InStripQuote := False;
end
else if not InStripQuote then
begin
StripQuoteChar := Result.Chars[I];
InStripQuote := True;
Result.Remove(I, 1);
end
end;
end;
我在使用 TPageProducer 时看到了这个调用,我可以看到我的良好源字符串进入上面的 ExtractHeaderFields 例程,然后进入“DoStripQuotes”函数。进入 DoStripQuotes 并观看“结果”表明它不会改变,即使调用 Result.Remove (以剥离报价)。当我将此“DoStripQuotes”例程用于一个简单的测试应用程序时,它不会编译,告诉我“Result.anything”是不允许的。我假设结果,虽然它被定义为“字符串”,但它必须是 Web.HTTPProd 上下文中的另一种类型的字符串。
所以我开始想,这可能与我听说过的“不可变字符串”有关。我读了这个SO question,虽然我明白了要点,但我可以提供更实用的建议。
具体来说,我想回答以下问题:
- 如果允许使用表示法 Result.Length,什么类型的“字符串”是“结果”?
- 有没有办法告诉编译器对一个单元使用“XE3”兼容性?(这可能让我看到问题的根源)。我试过 {$ZEROBASEDSTRINGS ON} / OFF 但这似乎会造成更多的混乱,我不知道我在做什么!
谢谢你的帮助。
稍后编辑:正如在下面接受的答案中指出的,这是 VCL 单元 Web.HTTPApp.pas 中的一个错误,它应该在第 2645 行周围的两个地方读取“Result := Result.Remove(I,1)”而不是“Result.Remove(I,1)”。删除(I,1)"