这个VB6方法在做什么?

时间:2012-10-30 04:59:14

标签: vb6

我们正在将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

好像它正在做一些二进制文件复制类型的东西,但我不太了解。有人可以解释一下我们可以改写它吗?

1 个答案:

答案 0 :(得分:8)

它将当前类(m_sEmailm_sName等)的成员序列化为fldAttach数据库字段作为字节数组。每个数据元素都以其大小为前缀,这就是为了写出每个数据的代码LngToByteArray(nSize)的原因。

在C#中,你使用MemoryStreamBinaryWriter来完成它的序列化方面,然后你将字节数组从内存流写入数据库。类似的东西:

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#代码必须处理这些代码。

有两个主要区别:一个是如何输出字符串 - 原始VB6代码不处理空字符串(VB6中没有这样的概念)。另一个是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#端口必须假定没有空字符串,否则它必须以某种方式处理它们。

最好编写一个通过数据库的小实用程序,并将所有记录更新为新格式,其中字符串具有空标记,长度前缀,然后是字符串字节。我个人会使用这个解决方案,因为那时新代码不必处理古老语言的怪癖。

PS:

请注意,VB6中的Long映射到C#中的int。这对于处理VB6二进制格式的长度前缀非常重要。

此外,这里有一个关于VB6字符串问题的链接 - 这在移植时可能很有用:

VB6 equivalent of string.IsNullOrEmpty