0

D2007からDXE2にいくつかのコードを移植しようとしています。この簡略化されたコードは、D2007で正常にコンパイルされます。DXE2では、次のエラーが表示されます。

[DCC Warning] Unit1.pas(10): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.
[DCC Error] Unit1.pas(37): E2010 Incompatible types: 'AnsiChar' and 'Char'

おそらくUnicodeの問題です。誰かがこれが起こる理由と私がそれを修正する方法を教えてもらえますか?

よろしく

コード:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TSetOfChar = Set of Char;  // Line 10

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FCharacterSet: TSetOfChar;
  public
    property CharacterSet: TSetOfChar read FCharacterSet write FCharacterSet;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  CharacterSet: TSetOfChar;
  j: Integer;
  s: String;
begin
  CharacterSet := [];
  s := 'I''m just testing åäö';

  for j := 1 to Length(s) do
    Include(CharacterSet, s[j]);  // <- Line 37

end;

end.

編集:ジェネリックを持たないDelphi2007を使用していることに注意してください。Unicodeに移植するコードがたくさんあるので、D2007でも機能するコードが必要です。これは遅いプロセスです。すべてが移植され、XE2で動作することを確認したら、ジェネリックなどのXE2を使用できます。その間、通常どおりD2007を維持し、リビジョン管理システムでXE2ブランチを作成することは避けたいと考えています。

4

1 に答える 1

8

これは標準のUnicodeDelphi移行飼料です。必要な読み物は、MarcoCantùの論文 White Paper: DelphiandUnicodeです。まだ読んでいない場合は、読んでください。最近読んでいない場合は、もう一度読んでください。

警告を生成する理由set of charは、セットの基本タイプが256を超える値を持つことはできないためです。しかし、char現在はUTF-16であるため、256をはるかに超えています。これはすべて、コードがセットやUTF-16文字で機能しないことを意味します。

set of AnsiCharとを使用できますAnsiString。ただし、このコードをUnicodeデータで機能させる場合は、以外のものを使用する必要がありますset。たとえば、TList<char>使用できます。

var
  CharacterSet: TList<char>;
  s: string;
  c: char;
.....
CharacterSet := TList<char>.Create;
s := 'I''m just testing åäö';
for c in s do
  if not CharacterSet.Contains(c) then
    CharacterSet.Add(c);

制作にはお勧めしません。その性能特性はひどいものになります。ハッシュベースの辞書の方がうまくいくでしょう。何よりも、専用の大規模なセットクラスになります。

最後にもう1つ。文字は、可変長エンコーディングであるUTF-16のコードポイントと同じではありません。問題のコードとこの回答はそれを考慮に入れていません。

于 2012-09-29T23:37:53.323 に答える