1

カスタムタイプの固定長文字列を使用する一部のVB6コードをUpgradeWizardを使用してVB.NETにアップグレードしましたが、誰かが助けてくれることを期待していたLSetメソッドの使用に問題があります。

既存のVB6コード(型宣言);

Public Type MyType
    PROP1       As String * 15
    PROP2       As String * 25
End Type

Public Type MyTypeBuffer
    Buffer As String * 40
End Type

使用例;

LSet instOfMyTypeBuffer.Buffer = ...
LSet instOfMyType = instOfMyTypeBuffer

これを.NETにアップグレードする適切な方法は何でしょうか?

UpgradeWizardを使用すると、次のようになります。

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
 _
Public Structure MyType
    <VBFixedString(15),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=15)> _
    Dim PROP1 As FixedLengthString

    <VBFixedString(25),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=25)> _
    Dim PROP2 As FixedLengthString

    Public Shared Function CreateInstance() As MyType
        Dim result As New MyType
        result.PROP1 = New FixedLengthString(15)
        result.PROP2 = New FixedLengthString(25)
        Return result
    End Function
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
 _
Public Structure MyTypeBuffer
    <VBFixedString(CLVHDR_REC_LENGTH),System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr,SizeConst:=40)> _
    Dim Buffer As FixedLengthString
    Public Shared Function CreateInstance() As MyTypeBuffer
        Dim result As New MyTypeBuffer
        result.Buffer = New FixedLengthString(40)
        Return result
    End Function
End Structure

FixedLengthStringは、名前空間Microsoft.VisualBasic.Compatibility.VB6から取得されます。

アップグレードウィザードが失敗するのは、LSetの場合です。それは以下を生み出しました。

instOfMyTypeBuffer.Buffer = LSet(...)
instOfMyType = LSet(instOfMyTypeBuffer)

これはコンパイルに失敗し、これらのエラーを引き起こします。

タイプ「String」の値を「Microsoft.VisualBasic.Compatibility.VB6.FixedLengthString」に変換できません

'Public Function LSet(Source As String、Length As Integer)AsString'のパラメーター'Length'に引数が指定されていません

タイプ「MyTypeBuffer」の値を「文字列」に変換できません

したがって、ToString()を使用してその方法の一部を取得できますが、それでもLSetメソッド呼び出し自体の問題があります。元の機能を再現するにはどうすればよいですか?アップグレードウィザードは私に完全に不適切な変換を与えましたか、それとも使用可能なものに回収できますか?

4

1 に答える 1

2

LSetは、VB6ではかなり風変わりなステートメントです。マニュアルの説明を参照してください。

  • 文字列に使用すると、元の文字列の文字列を左揃えにし、残った文字をスペースに置き換えます。
  • ユーザー定義型で使用すると、定義が異なっていても、あるユーザー定義型から別の型にメモリをコピーするだけです。これはお勧めしません。

それはあなたが持っているコードで特に風変わりな方法で使用されています。

  1. LSet instOfMyTypeBuffer.Buffer = ...
    これは、VB6と移行されたVb.Netの両方で冗長です。固定長の文字列に新しい値を割り当てると、とにかく常にスペースが埋め込まれます。
    したがって、これに変更するだけです(VB6またはVB.Netのいずれかで)
    instOfMyTypeBuffer.Buffer = ...
  2. LSet instOfMyType = instOfMyTypeBuffer
    もっと面白い。これにより、チェックなしで、あるタイプのインスタンスから別のタイプのインスタンスにメモリがコピーされます。ゴクゴク!
    タイプの定義を見ると、これは単純にから最初の15文字をに入れinstOfMyBufferinstOfMyType.PROP1残りの25文字をに入れると思いますinstOfMyType.PROP2
    これが、ファイルから読み取られた固定長の文字列レコードを処理するための醜い方法として使用されるのを時々見ました。たとえば、最初の15文字は人の名であり、次の25文字は最後の名前である可能性があります。
    このコード(VB6またはVB.Netのいずれか)に置き換えることができます。
    instOfMyType.PROP1 = Left(instOfMyBuffer.Buffer, 15)
    instOfMyType.PROP2 = Mid(instOfMyBuffer.Buffer, 16)

ハンスは、固定長のストリングを捨てることを提案しました。それが簡単な場合(そしてそれがコードベースの残りの部分に依存する場合、それは簡単かもしれませんし、難しいかもしれません)、それは良いアドバイスです。

于 2010-10-05T16:55:52.660 に答える