3

VB6 アプリケーションを C# (4.0) に変換しています。そして、理解するのに苦労している VB6 のメソッドに出くわしました。

Public Sub SaveToField(fldAttach As ADODB.Field)
    Dim bData() As Byte
    Dim nSize As Long

    nSize = Len(m_sEmail)
    bData = LngToByteArray(nSize)
    fldAttach.AppendChunk bData

    If nSize > 0 Then
        bData = StringToByteArray(m_sEmail)
        fldAttach.AppendChunk bData
    End If

    nSize = Len(m_sName)
    bData = LngToByteArray(nSize)
    fldAttach.AppendChunk bData
    If nSize > 0 Then
        bData = StringToByteArray(m_sName)
        fldAttach.AppendChunk bData
    End If

    bData = LngToByteArray(m_nContactID)
    fldAttach.AppendChunk bData

End Sub

バイナリファイルのコピー系の処理をしているようですが、よくわかりません。書き直すことができるように誰か説明してもらえますか?

4

1 に答える 1

8

現在のクラスのメンバー ( 、 など) をバイト配列としてデータベース フィールドにシリアルm_sEmailm_sNamefldAttachます。各データ要素にはそのサイズがプレフィックスとして付けられているため、LngToByteArray(nSize)書き出されたデータの各部分に対してコードが存在します。

C# では、MemoryStreamandを使用BinaryWriterしてシリアル化の側面を実現し、バイト配列をメモリ ストリームからデータベースに書き込みます。何かのようなもの:

byte[] byData;

using (MemoryStream oStream = new MemoryStream)
{
    using (BinaryWriter oWriter = new BinaryWriter (oStream))
    {
        if (m_sName == null)
        {
            oWriter.Write ((byte) 0); // null string
        }
        else
        {
            oWriter.Write ((byte) 1); // not a null string
            oWriter.Write (m_sName);
        }

        // other fields
    }

    byData = oStream.ToArray (); // get serialized byte array
}

// use byData here

編集: MarkJ はコメントで、このコードは元の VB6 コードと同じバイナリ形式を記述しておらず、似たようなものだけを記述していると指摘しました。VB6 コードによって記述されたレコードを含む既存のデータベースがある場合、C# コードはそれらを処理する必要があります。

2 つの大きな違いがあります。1 つは文字列の出力方法です。元の VB6 コードは null 文字列を処理しません (VB6 にはそのような概念はありません)。もう 1 つはBinaryWriter.Write(string)、長さの前に固定された文字列を自動的に書き込むことです。これは、長さを出力してから文字列バイトを出力する VB6 コードで使用される正確な形式である場合とそうでない場合があります。C# は、次のロジックを使用して、ここで VB6 コードを複製できます。

...

// assuming sStr is not null
byte[] byString = Encoding.Unicode.GetBytes ( sStr );

oWriter.Write ( sStr.Length );
oWriter.Write ( byString );

C# への移植では、null 文字列を想定しないか、何らかの方法で処理する必要があります。

データベースを調べてすべてのレコードを新しい形式に更新する小さなユーティリティを作成する方がよい場合があります。この形式では、文字列にヌル マーカー、長さの接頭辞、文字列のバイトが含まれます。新しいコードは古い言語の癖に対処する必要がないため、個人的にはこのソリューションを使用します。

PS:

LongVB6intでは C# にマップされることに注意してください。これは、VB6 バイナリ形式の長さのプレフィックスを処理するために重要です。

また、VB6文字列に関する質問へのリンクは次のとおりです。これは、移植が発生したときに役立つ場合があります。

string.IsNullOrEmpty に相当する VB6

于 2012-10-30T05:04:50.783 に答える