2012-01-16 11 views
5

私は古いプロジェクトのソースを手に入れていますが、少し変更する必要がありますが、デルファイ2010だけで済むので大変なことになりました。文字列の問題デルファイ3からデルファイ2010への移行

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

後でこの定義は、ファイルからの読み取りに使用されています:

b_bil: file of bbil; 
pbbil: ^bbil; 
l_bil : tlist; 

while not(eof(b_bil)) do 
    begin 
    new(pbbil); 
    read(b_bil, pbbil^); 
    l_bil.add(pbbil); 
    end 

主要な問題は、コンパイラは型「string」中を受け入れない定義された記録があり

彼は「ファイナライゼーション」を望んでいるからだ。 "string"を "string [255]"または "shortstring"に変更しようとしました。これを行うと、アプリケーションはファイルを読み込んでいますが、間違ったコンテンツを読み込んでいます。

私の質問は、私はすでに、例えば多くのことをしようとしたファイルが

デルファイ2010年に「新」タイプに書かれた古い「文字列」タイプを変換する方法であります"{$ H-}"レコードに1文字だけ追加すると、ファイルはほぼ正確に読み取られますが、各データセットで1文字ずつ切り捨てられるため、ファイルは正しくなります。lengthbyte + 255charsの長さは正しいと思われますが、shortstringは一致しません。

+0

両方Delphiで罰金を読み書きすることができるだろうレコード定義はコンパイラerrrorにも現れます: "finalize of bbil needed"。この方法でこれらのAnsiStringを短絡する "pfad:AnsiString [255];" "期待通りだが[見つかりました"]。私はおそらくShortAnsiStringが必要ですか? – rseffner

+2

IMOあなたのコードはDelphi 3でもコンパイルすべきではありません。 AnsiChar;の 'path:array [0..N]'を試してください。ここでNは何らかの定数で、おそらく255です。 – kludg

+2

Davidは言うとおり、文字列を 'ShortString'として宣言します。レコードのアライメントを行うには、パックされたレコード・ディレクティブを使用してください。このコードをD3で使用するには、{$ H-}指示文を使用していなければなりません。 –

答えて

5

Eek!それはあなたのコードの前日か長い文字列を使用していないようです。古いDelphiと同じ動作をさせたい場合は、stringShortStringに置き換える必要があります。

私はあなたがすでにそれを試して失敗したと報告しています。他のすべての文字列型は本質的にポインタなので、私にとって意味をなさないのは唯一の説明です。readがこれまでに働いた唯一の方法はShortStringです。あなたが試みているマイグレーションは膨大で、おそらく膨大な数の混乱する問題があります。

@LU RDは、packed配列を使用していないため、Delphiバージョン間でレコードレイアウトが異なる可能性があるという点で良い点があります。あなたが手にしている2つのDelphiのバージョンを使って、レコードのレイアウトを調べることができます。レコードのサイズがバージョン間で一致し、フィールドへのオフセットも一致するように調整する必要があります。

以下のコメントに基づいて、posとnrの間にパディングバイトを追加すると、問題が解決されます。

bbil = record 
    path : string; 
    pos: byte; 
    _pad: byte; 
    nr: Word; 
end; 

また、私は物事を行くとどのように考えるかだろう{$ALIGN ON}$ALIGNコンパイラオプションを設定することで同じ効果を得ることができました。

長い目で見れば、短い文字列、ANSIエンコーディング、内部レコードとデータファイル間の直接マッピングなどを避けなければなりません。短期的には、このコードを作成して使用するのと同じバージョンのDelphiを入手する方が良いかもしれません。私はこの問題が氷山の先端に過ぎないと思っています。

+0

David、私は 'ShortString'のアドバイスが正しいと思う。レコードのサイズだけが一致する必要がある。アライメント・ディレクティブは、これを解決するか、あるいはパックされたレコード宣言を解決することができます。 –

+0

レコードセットの "String"の代わりにShortStringを使用することは、私が最初にやったことの1つでした。しかし、それは期待どおりに動作しませんが、すべてのデータコードがゴミ箱になっていました;-(私は今、 "パックドレコードディレクティブ"について読んでいます - 私はそれを知らないので、 – rseffner

+1

'record'の代わりに' packed record'レコードのサイズを見るには 'SizeOf(bbil)'を使ってみてください。 –

2

ただ覚えている:

"文字列" <> "という文字列[255]" <> "ShortStringは" <を>戻る古いDOS /ターボパスカルの日中

をAnsiStringの、 "文字列は" 確かに限られていました255文字。ほとんどの場合、第1バイトには文字列の長さが含まれ、バイトには0〜255の値しかないためです。

これは現代版のDelphiではもう問題ではありません。

ShortString」は、古いDOS/Pascal文字列タイプのタイプです。

「LongString」は、現在、ほとんどの制作作業に使用しているBorland Delphi 2006を含む、長時間のデフォルトの文字列型です。 Delphi 3 .. Delphi 2009より、LongStringsは8ビット文字を保持し、使用可能なメモリのみによって制限されていました。 Delphi 3からDelphi 2009まで、 "LongStrings"は "AnsiStrings"と同義でした。

最近のバージョンのDelphi(Delphi 2009以降、新しいDelphi XE2を含む)は、すべてデフォルトでマルチバイトのUnicode "WideString"文字列になりました。 AnsiStringsと同様に、WideStringsも事実上最大限の長さで「無制限」です。

この記事では、より詳細に説明します。

http://delphi.about.com/od/beginners/l/aa071800a.htm

PSは: バイナリレコードに "はsizeof(bbil)" と "Packed" を使用することを検討してください。

+1

Delphiの用語では、長い文字列はAnsiStringとUnicodeStringの両方を指します。後者はD2009で導入された新しい文字列型です。そしてWideStringはもう一度異なっています、それはCOM BSTRのラッパーです。 –

+2

@rseffner - 用語が混乱する可能性があります。主にマイクロソフトの欠陥。文字列を理解するために私が引用したリンク(特に "about.com"記事)を見てください。バイナリレコードのパッキングとアライメントの問題を解決するには、sizeof()を試してください。 – paulsm4

+1

用語は完全に明確であり、MSとは関係ありません。問題の言語はEmbarcaderoによって生成されます。私の以前のコメントは、あなたの答えのさまざまなエラーを修正する方向にあなたを導くことを試みていました。それが立っているので、それはむしろ不正確です。 –

0

多分私は何かを見落としているかもしれませんが、私の見方では、あなたのデルファイ3のコードも壊れています。あなたのレコードデータを作り、 - (長さ1バイトのデータ用、残り1と256の間には何も)、POS(1バイト)、NR(2バイト)

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

パス:あなたのレコードのサイズを決定するために試してみてくださいサイズは、1 + 1 + 2 = 4バイトから256 + 1 + 2 = 259バイトまで変化する。その状況では、実際にデータを読み取る前に、プログラムが現在何バイトの読み込みを行うことができないので、どの場合でもファイルからガベージが取得されます。私は同じように、文字列は固定サイズであるように、あなたのレコードを修正する提案:次に

path : ShortString[255]; 

、あなたはでAnsiStringのを使用して3年と2010年

+0

また、delphi 3ではshortstring型がありませんでしたが、delphi 3では文字列として定義する必要があります。 –